TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: SteveK on November 24, 2009, 08:22:33 PM

Title: A couple of small *error* questions
Post by: SteveK on November 24, 2009, 08:22:33 PM
Hi,

If someone has a minute can you guys help me clear a knowledge aspect up in my mind?

Q1. Why do you need to localise a local *error* function when you don't need to localise other local functions?
eg:
Code: [Select]
(defun func1 (/ [color=red]*error*[/color])
;; Localise this function
(defun *error* ()
<code>
)
;; But not localise this function
(defun func2()
<code>
)
)

Q2. And if I have a function that calls a few other functions, is it best to make the *error* function local in that function, or have it temporarily global.
eg, this:
Code: [Select]
(defun func1 (/ [color=blue]*error*[/color])
[color=blue](defun *error* ()
<code>
)[/color]
(func2)
(func3)
)
(defun func2()
<code>
)
(defun func3()
<code>
)
or this:
Code: [Select]
(defun func1 (/ [color=green]*error*[/color])
[color=green](setq temperr *error*)
(setq *error* errortrap)[/color]
(func2)
(func3)
[color=green](setq *error* temperr)[/color]
)
[color=green](defun errortrap ()
<code>
)[/color]
(defun func2()
<code>
)
(defun func3()
<code>
)
Thanks
Title: Re: A couple of small *error* questions
Post by: Kerry on November 24, 2009, 09:42:48 PM

Quote
Q1. Why do you need to localise a local *error* function when you don't need to localise other local functions?

Because AutoCAD has a global *error* function defined. Defining your own and making it local saves all the save and restore loops needed to reduce the possibility of overriding the default function.

demo of default :

Code: [Select]
(defun c:test_00 (/ )
  (vl-load-com)
  ;;-----------------------------------------------------------
  (defun _internal_00 () (/ 1 0) (princ))
  ;;-----------------------------------------------------------    
  (princ)
)

Command: TEST_00
; error: divide by zero

Command:
Command: (_internal_00)
; error: divide by zero


Quote
Q2. And if I have a function that calls a few other functions, is it best to make the *error* function local in that function, or have it temporarily global.

Make it local to the Main.


eg:
Library routine
Code: [Select]
;;;------------------------------------------------------------------
;;;------------------------------------------------------------------
;;;
(pragma '((unprotect-assign template:on-error)))
;;
(defun template:on-error (msg / tmp)
  ;;----- Cancel any Active Commands -----------------------------
  (while (< 0 (getvar "cmdactive")) (command))
  (setvar "menuecho" 1)
  (vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))
  ;;----- Display error message if applicable _-------------------
  (cond ((not msg))                          ; no error, do nothing
        ((member
           (strcase msg t)                   ; cancel
           '("console break" "function cancelled" "quit / exit abort")
         )
        )
        ((princ (strcat "\nApplication Error: "
                        (itoa (getvar "errno"))
                        " :- "
                        msg "\n"
                )
         )
         ;;----- Display backtrace if in debug mode ---------------------
         (if kglobal:debug_on
           (vl-bt)
         )
        )
  )
  ;;----- Reset System Variables from global list ----------------
  (foreach item kglobal:sysvarlist (setvar (car item) (cadr item)))
  (setq kglobal:sysvarlist nil)
  (princ)
)
;;
(pragma '((protect-assign template:on-error)))
;;


Demo Code:
Code: [Select]
(defun c:test_01 (/ *error*)
  (vl-load-com)
  (defun *error* (msg /) (template:on-error msg) (princ))
  ;;-----------------------------------------------------------
  (defun _internal_01 () (/ 1 0) (princ))
  ;;-----------------------------------------------------------  
  (_internal_01)
  (*error* nil)
  (princ)
)
;;;------------------------------------------------------------------
;;;------------------------------------------------------------------
;;;

Command: TEST_01
Application Error: 93 :- divide by zero
Command:

Command: (_internal_01)
; error: divide by zero

Code: [Select]
(defun c:test_02 (/ *error*)
  (vl-load-com)
  (defun *error* (msg /) (template:on-error msg) (princ))
  ;;-----------------------------------------------------------
  (defun _internal_01 () (/ 1 0) (princ))
  ;;-----------------------------------------------------------  
  (_external_01)
  (*error* nil)
  (princ)
)
;;;------------------------------------------------------------------
;;;------------------------------------------------------------------
;;;
(defun _external_01 () (/ 1 0) (princ))

Command: TEST_02
Application Error: 93 :- divide by zero
Command:

Command: (_external_02)
; error: divide by zero
Title: Re: A couple of small *error* questions
Post by: Kerry on November 24, 2009, 09:51:10 PM

and if you want to add to the error function ...

Code: [Select]
(defun c:test_03 (/ *error* _internal_03)
  (vl-load-com)
  (defun *error* (msg /)
    (template:on-error msg)
    (if msg
      (princ (strcat "\nJust to proove a point : \n"))
    )
    (princ)
  )
  ;;-----------------------------------------------------------
  (defun _internal_03 () (_external_02) (princ))
  ;;----------------------------------------------------------- 
  (_internal_03)
  (*error* nil)
  (princ)
)
;;;------------------------------------------------------------------
;;;------------------------------------------------------------------
;;;
(defun _external_02 () (/ 1 0) (princ))
;;;------------------------------------------------------------------
;;;------------------------------------------------------------------
;;;

Command: TEST_03
Application Error: 93 :- divide by zero
Just to proove a point :
Title: Re: A couple of small *error* questions
Post by: SteveK on November 24, 2009, 11:22:01 PM
Cheers Kerry, that's what I wanted to know. I didn't think enough about that first question. Thanks a lot.