Descrizione

Per coloro che vogliono sviluppare in AutoLISP nei CAD AutoCAD compatibili (che non dispongono di un ambiente IDE - tipo Visual LISP) è possibile utilizzare questa funzione all'interno del loro codice per stoppare il programma e eseguire il cosidetto 'debug'.

Per riuscire a trovare la causa di un errore in un programma è necessario verificare a volte passo a passo le istruzioni, controllando che ogni variabile, ogni risultato sia quello previsto e che non contrasti con le istruzioni successive.

Quante volte sarà capitato a programmatori alle prime esperienze di passare ad una funzione un argomento di tipo sbagliato, ad esempio (atoi 5) invece che (atoi "5").

Non essendoci all’interno di alcuni CAD AutoCAD compatibili un ‘debugger’, per ispezionare lo stato delle variabili durante il corso del programma si adotta la classica tecnica di far stampare il valore di queste a video, per poi capire in quale parte del programma si commette l’errore, ad esempio:

... 
(setq x(nth 1 lista)) ; la variabile x viene inizializzata 
(print x) ; stampa a video il valore di x 
(grread) ; eventuale pausa per leggere il risultato 
... 

Il programma che presentiamo, ddDEBUG, adotta lo stesso principio solo che grazie all’utilizzo dei dialog box, riesce ad offrire alcuni vantaggi quali:

la possibilità di verificare il valore di più variabili (o espressioni)

la possibilità di assegnare nuovi valori alle variabili oggetto di valutazione.

In pratica il flusso del programma principale viene momentaneamente ‘stoppato’ dalla funzione (ddd) che ci permette di valutare lo stato delle variabili grazie al dialog box composto semplicemente da 2 edit_box e da un button.

dd debug ui

 

Il primo edit_box serve ad immettere il nome della variabile oppure dell’espressione che si desidera valutare; ad esempio si potrebbe immettere ‘pi’ oppure un’espressione tipo (car(nth 3 lista)).

Premendo il tasto invio il programma valuta il contenuto dell’edit_box (con la funzione Valuta) e poi visualizza il valore o il risultato nel secondo edit_box, quello centrale, in realtà sarebbe stato più giusto adoperare un elemento TEXT per visualizzare il risultato ma con un edit_box è possibile eseguire uno scroll laterale e quindi di consultare risultati più lunghi (pensiamo ad una lista con molti elementi).

Infine un button ed una altro edit_box permettono di re-inizializzare la variabile con un nuovo valore (funzione Nuovoval) in modo che l’esecuzione del programma continui con la variabile settata con un valore noto.

Per richiamare la funzione ddDebug scrivere appena dopo le istruzioni sospette (ddd) così:

...

(setq x(nth 1 lista));la variabile x viene inizializzata 
(ddd) ;funzione per richiamare ddDebug

...

Ma analizziamo il codice, peraltro semplicissimo. Una prima funzione, Valuta, ha il compito di valutare appunto la stringa passatagli come argomento e scriverla nel secondo edit_box:

(eval (read #a))

il risultato viene scritto in un file così poi, rileggendolo, potrà essere gestito come stringa (unico tipo di dato accettato dagli elementi dei dcl) quindi:

 (prin1 (eval (read #a)) #fi)

Basta un read-line per inizializzare il secondo edit_box (quello con la key = "e2")

(set_tile "e2" (read-line #fi)) 

Ancora più breve e semplice la funzione Nuovoval che, dopo aver verificato che la stringa presente nel primo edit_box sia valida per essere utilizzata come nome di simbolo

(if (= ‘SYM (type (read (get_tile "e1"))))

le assegna il valore immesso nel terzo edit_box utilizzando la funzione set

 (set (read (get_tile "e1")) (read new))

Ricordate che per assegnare una stringa si dovranno racchiudere i caratteri tra virgolette ("").

Di seguito il codice sorgente AutoLISP e DCL , la funzione può anche essere utile richiamarla da linea di comando per questo definiamo il nuovo comando DDD

(defun c:ddd () (ddd)) 
;;
;; DD Debug 
;; revisione 4 - 20/10/95
;; ...by Domenico Ieva 
(defun ddd ( / valuta nuovoval new dcl_id )
       ;;;
       ;;; VALUTA
       ;;; 
       (defun valuta (#a / #fi)
        (if (read #a) ; se diverso da nil
         (progn
           (setq #fi(open "ddd.tmp" "w"))
           (prin1 (eval (read #a)) #fi)  
           (close #fi)
           (setq #fi(open "ddd.tmp" "r"))
           (set_tile "e2" (read-line #fi))
           (close #fi)
           (mode_tile "nv" 0) ;attiva il button...
          )
          (progn
            (alert"Manca nome variabile o espressione")
            (mode_tile "e1" 2)  ; rimette focus su edit box
           )
         )
 )
       
     ;;;
     ;;; NUOVOVAL
     ;;; Assegna nuovo valore a variabile
    (defun nuovoval ()
       (if (= 'SYM (type (read (get_tile "e1"))))  ;;se la variabile è un simbolo
        (progn
         (set (read (get_tile "e1")) (read new))
         (set_tile "e2" new)
         )
         (alert(strcat "Attenzione '" (get_tile "e1") "' non e' un simbolo (tipo SYM)"))
        )
      )
    ;; 
    ;;
    (if (>= (setq dcl_id (load_dialog (findfile "debug.dcl"))) 0)
     (progn
       (setq new "") 
       (new_dialog "dddebug" dcl_id)
       (mode_tile "nv" 1)
       (action_tile "e1" "(if $value (valuta $value))")
       (action_tile "e3" "(setq new $value)")  
       (action_tile "nv" "(nuovoval)")
       (start_dialog)               
       (unload_dialog dcl_id)       
      )
      (alert"\nNon trovo il file 'DEBUG.DCL'.")
      )
    )
(defun c:ddd ()(ddd))
//////////////////////// DEBUG.DCL
dddebug: dialog
       { label = "* DD D e b u g *";
       initial_focus = "e1";
       :edit_box{ label = "espressione/variabile:";
             key = "e1"; edit_width = 12;}
       :boxed_column {
       :text { label = "valore:"; }
       :edit_box{ key = "e2";}
            }
       :boxed_row {
       :button {label = "Assegna nuovo valore:"; 
                    key = "nv"; mnemonic = "A";}
       :edit_box {key = "e3"; edit_width = 12;} 
       }
       ok_only;
       }

Download

scarica file: dddebug.zip ( 1 kb) download