(defun c:xxx(/ *error* cl )
(defun *error* (msg)
(redraw)
(if cl
(setvar 'clayer cl)
)
(if (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
(princ msg)
(princ (strcat "\n** Error: " msg " **"))
)
)
(setq vars (mapcar '(lambda (x) (cons x (getvar x))) '("clayer" "textstyle")))
(defun *error* (msg)
;; Reset variables
(mapcar '(lambda (x) (setvar (car x) (cdr x))) vars)
(if (not (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*"))
(princ (strcat "\nError: " msg))
)
(princ)
)
(defun c:xxx(/ *error* cl ts )
(defun *error* (msg)
(redraw)
(if cl
(setvar 'clayer cl)
)
(if ts
(setvar 'TEXTSTYLE ts)
)
(if (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
(princ msg)
(princ (strcat "\n** Error: " msg " **"))
)
)
Try something like this:Code: [Select](setq vars (mapcar '(lambda (x) (cons x (getvar x))) '("clayer" "textstyle")))
(defun *error* (msg)
;; Reset variables
(mapcar '(lambda (x) (setvar (car x) (cdr x))) vars)
(if (not (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*"))
(princ (strcat "\nError: " msg))
)
(princ)
)
(mapcar '(lambda (x) (setvar (car x) (cdr x))) vars)
Try something like this:Code: [Select](setq vars (mapcar '(lambda (x) (cons x (getvar x))) '("clayer" "textstyle")))
(defun *error* (msg)
;; Reset variables
(mapcar '(lambda (x) (setvar (car x) (cdr x))) vars)
(if (not (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*"))
(princ (strcat "\nError: " msg))
)
(princ)
)
(defun c:test ( / *error* osm )
(defun *error* ( msg )
(if osm (setvar 'osmode osm))
(if (not (member msg '("Function cancelled" "quit / exit abort")))
(princ (strcat "\nError: " msg))
)
(princ)
)
(setq osm (getvar 'osmode))
(setvar 'osmode 0)
(rtos (getreal "\nPress Esc to exit, press Enter to force an error ..."))
(setvar 'osmode osm)
(princ)
)
You can add whatever other variables you want to this portion of the code:
'("clayer" "textstyle")
That's the beauty of it :)
(setq vars (mapcar '(lambda (x) (cons x (getvar x))) '("clayer" "textstyle" "osmode")))
(defun *error* (msg)
;; Reset variables
(mapcar '(lambda (x) (setvar (car x) (cdr x))) vars)
(if (not (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*"))
(princ (strcat "\nError: " msg))
)
(princ)
)
;;; --- ai_sysvar ------------------------------------------
;;; Change system variable settings and save current settings
;;; (Note: used by *merr* to restore system settings on error.)
;;;
;;; The <vars> argument is used to...
;;; restore previous settings (ai_sysvar NIL)
;;; set a single sys'var (ai_sysvar '("cmdecho" . 0))
;;; set multiple sys'vars (ai_sysvar '(("cmdecho" . 0)("gridmode" . 0)))
;;;
;;; defun-q is needed by Visual Lisp for functions which redefine themselves.
;;; it is aliased to defun for seamless use with AutoLISP.
Hi,
To set and restore system variables, you can also the ai_sysvar function.
This function is available in AutoCAD since a while.
It's defined in acaddoc20XX.lsp (ai_utils.lsp or acad.mnl in older versions), so it's automatically loaded in each document.Quote;;; --- ai_sysvar ------------------------------------------
;;; Change system variable settings and save current settings
;;; (Note: used by *merr* to restore system settings on error.)
;;;
;;; The <vars> argument is used to...
;;; restore previous settings (ai_sysvar NIL)
;;; set a single sys'var (ai_sysvar '("cmdecho" . 0))
;;; set multiple sys'vars (ai_sysvar '(("cmdecho" . 0)("gridmode" . 0)))
;;;
;;; defun-q is needed by Visual Lisp for functions which redefine themselves.
;;; it is aliased to defun for seamless use with AutoLISP.
Anywhere in the code, you can call ai_sysvar to save the current value of one or more sysvar and set it a new value (or not).
Example:Code - Auto/Visual Lisp: [Select]
;; save and set "osmode" to 0 (ai_sysvar '("osmode" . 0)) ... ;; save and set "orthomode" to 1 and only save "autosnap" (ai_sysvar '(("orthomode" . 1) ("autosnap" . nil))) ... ;; restor all sysvars (ai_sysvar nil)
<EDIT> I forgot to say, the implementation of ai_sysvar is quite interesting with the use of defun-q which allows to store the list of var names ans values within the function.
Yes
(setq vars (mapcar '(lambda (x) (cons x (getvar x))) '("clayer" "textstyle" "osmode")))
(defun *error* (msg)
;; Reset variables
(mapcar '(lambda (x) (setvar (car x) (cdr x))) vars)
(if (not (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*"))
(princ (strcat "\nError: " msg))
)
(princ)
)
;;start;(command "_.undo" "be")
(defun _StartUndo (*DOC*)
(_EndUndo *DOC*)
(vla-StartUndoMark *DOC*)
)
;;end;(if (= 8 (logand (getvar "undoctl") 8)) (command "_.undo" "_e"))
(defun _EndUndo (*DOC*)
(if (= 8 (logand 8 (getvar 'UNDOCTL)))
(vla-EndUndoMark *DOC*)
)
)
(if (not (wcmatch msg "*EXIT*,*BREAK*,*CANCEL*"))
(progn
(princ "\n*** error ***\n")
(princ (strcat "\t" name ": " (vl-princ-to-string msg) "\n"))
(*error* msg)
(princ)
)
)
@ Reltro:
Interesting code. I have a question about this portion:Code: [Select](if (not (wcmatch msg "*EXIT*,*BREAK*,*CANCEL*"))
(progn
(princ "\n*** error ***\n")
(princ (strcat "\t" name ": " (vl-princ-to-string msg) "\n"))
(*error* msg)
(princ)
)
)
If an EXIT/BREAK/CANCEL error occurs the restored *error* function is not called meaning only a single level is undone.
If a different error occurs the restored *error* function is called meaning all levels are undone. And there will also be a superfluous call to the 'default' *error* function.
I may be missing something but this does not seem logical.
(INIerror "This is a function ...")
(setvar "osmode" 0)
(setvar "cmdecho 0)
.
.
.
.
(*error* nil)
I'm not sure if this is good stuff or not...
Im overwriting setvar to catch all changes and restore changed sysvars if an error occurs or the errorHandler is called with nil...Code - Auto/Visual Lisp: [Select]
USAGE:Code: [Select](INIerror "This is a function ...")
(setvar "osmode" 0)
(setvar "cmdecho 0)
.
.
.
.
(*error* nil)
reltro
(defun c:test ( / *error* ... )
(defun *error* ( msg )
;; stuff here
)
;; stuff here
; force a clean-up
(*error* nil )
(princ)
)