|
|||||||||||||||||||||||||||||||||||||||||||
|
Nous avons vu comment on pouvait suivre, et éventuellement mémoriser, le déroulement d'un programme afin d'en détecter les défauts divers. Il reste encore quelques possibilités intéressantes, que nous allons analyser. Traçage interactif Nous avions précédemment laissé de côté le traçage interactif, non pour le négliger, bien au contraire : il permet de modifier momentanément le programme en cours (valeur ou instruction). L'intérêt en est considérable et la mise en oeuvre très simple. Il y a deux façons d'entrer dans le mode interactif : 1. A partir de l'intérieur du programme, en ajoutant un "?" à l'instruction "TRACE" en complément avec n'importe quelle option. Exemple : "TRACE ?" ou encore "TRACE ? INTERMEDIATES". Attention à la place relative de l'option et du "?". La commande du mode interactif agit en mode alterné (toggle) : "TRACE ?" lance le mode interactif, puis "TRACE ?" à nouveau l'arrête, et ainsi de suite. 2. A partir de l'extérieur, en lançant le programme TS (fourni avec ARexx). Dans ce cas, tous les programmes ARexx en cours entrent en mode interactif. TS (Trace Start) a son opposé TE (Trace End), qui permet de sortir du mode interactif. Le mode interactif arrête le programme après chaque instruction ARexx sauf pour CALL, DO, ELSE, IF, THEN et OTHERWISE qui pourraient poser des problèmes à l'interpréteur. Pour ces instructions, l'arrêt est effectué à la fin de l'exécution totale de l'instruction. En outre, l'interpréteur ne s'arrêtera pas après une instruction qui aurait déclenché une erreur, son traitement étant prioritaire. Lorsque l'interpréteur est arrêté par le mode interactif, quel qu'en ait été le mode de lancement, le symbole "+++" apparaît dans la fenêtre de traçage. A partir de cet instant, trois actions peuvent être réalisées : 1. Une ligne vide, sanctionnée par un simple appui sur la touche "Entrée", permet au programme de continuer son exécution jusqu'au point d'arrêt suivant. 2. Un signe "=" suivi de l'appui sur la touche "Entrée" permet à l'instruction précédant l'arrêt d'être exécutée une nouvelle fois. 3. L'entrée d'une instruction valide quelconque, qui est exécutée tout de suite après l'appui sur la touche "Entrée". Comme il a été vu précédemment, les instructions de type DO ou SELECT doivent être complétées avant l'appui sur la touche "Entrée" pour ne pas plonger l'interpréteur dans une profonde angoisse qui l'inciterait à faire méditer le Guru. Traitement des erreurs Heureusement, ARexx procure un traitement d'erreurs spécial pendant qu'il fonctionne en mode interactif, qui fournit un rapport pour chaque erreur mais ne provoque pas l'arrêt du programme (ce qui en serait normalement la conséquence). Cette particularité ne s'applique qu'aux instructions qui ont été entrées en mode interactif (ouf !). Les erreurs dues aux défauts du programme sont traitées par la méthode normale. En plus de ce traitement spécial et en mode interactif uniquement, l'interpréteur désactive les indicateurs internes d'interruption. C'est indispensable pour éviter le transfert vers le traitement d'erreur éventuellement intégré au programme (voir chapitre suivant). Une exception cependant pour les instructions de type SIGNAL qui continuent non seulement à autoriser le transfert mais qui font abandonner ce qui pouvait rester comme entrée interactive en suspens. Interruptions ARexx entretient un système interne d'interruption qui peut être utilisé pour détecter et piéger certaines conditions d'erreur. Lorsqu'une interruption est activée (mise en état de fonctionner) et que les conditions de déclenchement correspondantes se présentent, le programme est dévié vers un sous-programme dont le nom est spécifique de l'interruption, pour peu qu'on ait pris soin d'en écrire un. Les conditions d'interruption peuvent être synchrones, telles que les erreurs de syntaxe, ou asynchrones, telles que les demandes au clavier, "Control-C" par exemple. Il faut noter que les interruptions extérieures sont complètement séparées des interruptions matérielles gérées par Exec. Liste des interruptions reconnues Certaines des interruptions ont des comportements différents selon qu'elles sont activées ou non, d'autres n'ont qu'un type de comportement efficace seulement après activation.
Utilisation des interruptions Nous venons de voir que les interruptions ont un comportement différent suivant qu'elles sont activées ou non. Le comportement non activé ayant été décrit, voyons comment les utiliser en mode activé. Il faut réaliser deux opérations : activer l'interruption souhaitée et écrire le sous-programme de traitement. La forme générale d'activation est "SIGNAL ON label", où "label" est le nom d'une des interruptions décrites plus haut. Par exemple, "SIGNAL ON NOVALUE" s'inquiétera dès que le programme tentera d'utiliser une variable non initialisée. A l'arrivée de la condition, le déroulement du programme sera dévié vers un sous-programme de traitement de cette interruption. L'instruction "SIGNAL ON" est semblable au "GOTO" prohibé de tous les programmes respectables. Dans le cas présent, et ailleurs aussi, parce que c'est une nécessité, il faut réaliser un transfert impératif, d'où cette forme. Le sous-programme intéressé se nommera donc "label" (dans le cas de l'exemple, "NOVALUE:"). A partir de l'entrée dans le sous-programme on revient à de la programmation classique. On peut ainsi donner une valeur arbitraire à la variable non initialisée et retourner à la suite du programme, ou encore solliciter l'opérateur avec un texte lui demandant une valeur de son choix et utiliser la capacité du PARSE (PARSE PULL ou tout simplement la forme abrégée PULL) et retourner au programme pour continuer. Le choix du retour et à la continuation du programme dépend de la volonté et du besoin du programmeur. Enfin, pour désactiver "SIGNAL ON label" on utilisera son contraire, "SIGNAL OFF label", ce qui permet une jolie série de combinaisons ON/OFF de toutes les formes possibles d'interruption, sélective en forme, en activation, et donc en position et en répétition. Signalons (sans jeu de mots...) une forme un peu plus complexe de SIGNAL : "SIGNAL VALUE expression", qui agit comme un GOTO càlculé c'est-à-dire qu'il y a transfert vers un sous-programme de traitement d'erreur qui dépend de l'évaluation de l'expression. Le type de l'interruption est défini par une variable spécifique dont nous allons nous occuper maintenant. Variables "SIGL" et "RC" Ces deux variables ont des noms réservés, au même titre que les mots spécifiques du langage : DO, PARSE et tous les autres. Elles sont constamment mises à jour pendant l'exécution du programme et peuvent être consultées à tout moment. La variable SIGL (pour SIGnaL) contient le numéro de la ligne qui précède celle qui a déclenché le transfert vers le traitement d'erreur. Attention, si vous avez utilisé la faculté légale d'écrire plusieurs instructions sur la même ligne, séparées par un point-virgule, vous risquez de ne pas retrouver aisément celle qui est la cause de l'interruption. La variable RC (pour Return Code), contient, elle, le résultat des interruptions ERROR et SYNTAX en cas d'erreur et une autre valeur en cas de bon fonctionnement. Pour ERROR, le résultat usuel est le niveau de sévérité de l'erreur et il peut venir de l'extérieur. Pour SYNTAX, le résultat est toujours un code erreur ARexx. Par exemple, si l'erreur est la numéro 3 et la sévérité 20, on en déduit qu'il y a une quantité de mémoire insuffisante en se référant à la liste des codes d'erreurs fournie avec la documentation d'ARexx. La variable RC n'est pas toujours d'un maniement aussi limpide, surtout lorsqu'elle est affectée par un élément extérieur à ARexx. En principe, tout appel à une fonction extérieure, du système d'exploitation par exemple, devrait donner une valeur au RC et, si cela est réputé vrai avec AmigaOS 2 des Amiga 3000 (ARexx fait partie de son environnement) cela ne l'est sûrement pas pour les AmigaOS 1.1 à 1.4 des "petits" Amiga. L'emploi du RC doit donc être soumis à l'essai pour avoir une idée de la vérité. Enfin, avant de donner des exemples d'emploi, il faut avoir en tête que le RC est affecté par le retour de l'appel à une fonction et qu'il a de ce fait, une valeur très rapidement caduque. Exemples d'utilisation de RC La valeur de retour de RC est dite booléenne, c'est-à-dire qu'elle vaut 1 en cas de mauvaise exécution et 0 sinon. C'est en tout cas le fonctionnement qu'elle devrait avoir d'après les livres... Pour se faire une idée, on pourra avec profit utiliser le petit programme suivant qui permet d'effectuer divers essais. Ce programme permet l'entrée au clavier de diverses instructions ARexx et l'on pourra regarder avec intérêt ce qui se passe en cas de défaut dans l'orthographe, la syntaxe ou encore dans le système. Il est prévu trois cas de RC : 0, autre. Installation Nous allons maintenant présenter une organisation qui permet d'écrire les lignes de code, de voir le résultat à l'exécution et de surveiller le déroulement dans la fenêtre spécialisée. On doit trouver les programmes suivants dans le répertoire C courant : HI, TCO, TCC, TE, TS, en plus de RX, RXC et RXSET. On ouvre une console CONMAN par exemple (recommandé). On ouvre l'éditeur de texte de son choix. On ouvre enfin la fenêtre de messages d'erreur par TCO. Les fenêtres sont réparties de la façon suivante : l'éditeur occupe les 2/3 supérieurs de l'écran, la console le 1/3 inférieur et la fenêtre de surveillance est en haut à droite. Tout ceci doit se trouver dans la startup-sequence, comme il est indiqué dans la documentation. De plus, pour éviter de cliquer à chaque fois dans les fenêtres, il est agréable d'installer DMouse de Matt Dillon. Enfin, on peut fermer la fenêtre de début qui ne sert plus à rien. On peut alors taper un programme dans la fenêtre de l'éditeur, le sauvegarder, le faire s'exécuter dans la console... A ce propos, il est recommandé de lancer l'exécution par "RUN RX" plutôt que par "RX" tout court, car en cas de boucle infinie imprévue dans le programme, l'envoi de HI permet de tout arrêter... sans devoir redémarrer ! On se méfiera toutefois des programmes qui utilisent "PARSE PULL" pour demander quelque chose à l'opérateur, car ils lisent d'abord la console et on obtiendrait une erreur car ils liront le retour de RUN. Pour ceux-là, si l'on ne veut pas changer de méthode d'appel, on placera une condition d'arrêt interne et on ne les lancera pas avec RUN. On lancera de la même façon le traçage interactif et toutes les options que nous avons analysées.
|