Sortie silencieuse d'un programme AutoLISP

Dans la plupart des programmes, on a besoin de terminer immédiatement l'exécution lorsqu'on tombe sur une erreur. Par exemple, dans le programme ci-dessous, on veut terminer immédiatement si le fichier foo n'est pas trouvé.

(defun silent-exit ()
  (if (not (findfile "foo"))
        (progn
            (alert "Fichier foo non trouvé.")
            (exit)
        )
  )
  ;; Exécution du reste du programme
  (princ)
)

Le problème, c'est que quand on utilise la fonction exit ou quit, on a un disgracieux message d'erreur qui s'affiche sur la ligne de commande :

; erreur: quitter / sortir abandon

Pour éviter cela, il faut mettre en place un gestionnaire d'erreur personnalisé :

(defun my-error (msg)
  (if
    (/= (getvar "ERRNO") 100)
     (princ (strcat "\nErreur : " msg))
  )
  (setq *error* *ini-err* *ini-err* nil)
  (princ)
)
 
(setq *ini-err* *error*
      *error* my-error
)
 
(defun silent-exit ()
  (if (not (findfile "foo"))
    (setvar "ERRNO" 100)
    (exit)
  )
  (setq *error* *ini-err* *ini-err* nil)          
  (princ)
)

On définit tout d'abord une fonction my-error qui va être appelée par AutoCAD lorsqu'une erreur survient. L'argument msg correspond au message d'erreur.

On pourrait inspecter ce message pour ne pas l'afficher si il correspond à erreur: quitter / sortir abandon, mais le problème c'est que ça ne fonctionnerait que sur un AutoCAD français.

L'astuce consiste à utiliser la variable système ERRNO. Cette variable est modifiée par AutoCAD lorsqu'une erreur survient dans un programme AutoLISP (vous pouvez consulter la liste des différentes valeurs que peut prendre la variable système ERRNO d'erreurs ici).

Dans notre cas, comme c'est nous qui provoquons l'erreur à l'aide de la function exit, la variable ERRNO ne va pas être mise à jour. On la mets donc explicitement à une valeur qui n'est pas encore prise avec setvar (une valeur égale ou supérieure à 100 peut faire l'affaire puisque à aujourd'hui le code d'erreur le plus grand est 85).

On peut ensuite tester cette variable. Si elle est à 100, on sort sans afficher de message, sinon on affiche le message d'erreur standard.

Pour mettre en place notre gestionnaire, on commence par mémoriser dans une variable globale nommée *ini-err* le gestionnaire d'erreur par défaut de façon à pouvoir le restaurer à la fin de notre programme. On place ensuite notre fonction my-error dans la variable globale *error*.

Etiquettes:

Ajouter un commentaire