Sviluppo

Corso di programmazione in REXX - Lezione 4 - nozioni avanzate

Alessandro Cantatore
 


Il REXX e i file batch
Il REXX può sempre sostituire i file batch. I seguenti esempi permettono di paragonare un file batch all'equivalente programma REXX.

rem HELP.CMD (versione batch OS/2)
@echo off
if %1.==. goto msg
if %1 == on goto yes
if %1 == off goto no
if %1 == ON goto yes
if %1 == OFF goto no
if %1 == On goto yes
if %1 == oN goto yes
if %1 == OFf goto no
if %1 == OfF goto no
if %1 == Off goto no
if %1 == oFF goto no
if %1 == oFf goto no
if %1 == ofF goto no
helpmsg %1
goto exit
:msg
helpmsg
goto exit
:yes
prompt $i[$p]
goto exit
:no
cls
prompt
:exit
Il programma REXX equivalente è:
/* HELP.CMD - ottiene l'help per un messaggio di sistema */
arg action .
select
  when action=''    then     'helpmsg'
  when action='ON'  then     'prompt $i[$p]'
  when action='OFF' then do
                           'cls'
                           'prompt'
                           end
  otherwise 'helpmsg' action
  end
exit

Trapping degli errori nell'esecuzione dei comandi
Il miglior sistema per rilevare l'errata esecuzione di un comando richiede l'uso di condition traps tramite le istruzioni SIGNAL ON e CALL ON con la condizione ERROR o FAILURE.
Quando vengono usate in un programma queste condizioni abilitano nell'interprete del REXX un rilevatore che controlla il risultato di ciascun comando. Quando un errore viene rilevato, l'interprete ferma la normale elaborazione dello script, cercando nello stesso l'etichetta ERROR: o FAILURE: o un'altra etichetta definita dal programmatore, continuando l'elaborazione da essa.

Le istruzioni SIGNAL ON e CALL ON inoltre fanno sì che l'interprete del REXX memorizzi il numero di riga dello script in cui è il comando che ha provocato la rilevazione della condizione di errore.
Tale numero di riga viene assegnato ad una variabile speciale chiamata SIGL. Il programma può ottenere maggiori informazioni sulla causa dell'errore attraverso la funzione inclusa CONDITION().

L'uso delle istruzioni CALL e SIGNAL comporta diversi vantaggi:

  • I programmi sono più comprensibili perchè la rilevazione degli errori viene delegata ad una singola routine comune a tutte le condizioni di errore.
  • I programmi sono più flessibili perché possono rispondere ad una condizione di errore riportando la riga di codice che ha causato l'errore (SIGL), il valore restituito dal comando (RC) o altre informazioni (CONDITION).
  • Il programma che rileva un errore può intraprendere un'azione appropriata prima che l'errore venga rilevato dall'ambiente in cui viene eseguito lo script.
  • Le condizioni di trap possono essere facilmente disabilitare tramite SIGNAL OFF e CALL OFF.
In una delle prossime lezioni tratteremo l'argomento delle altre condizioni che è possibile rilevare tramite SIGNAL ON e CALL ON.

Istruzioni e condizioni
Le istruzioni per la rilevazione degli errori sono:

SIGNAL ON condition [NAME trapname]
CALL   ON condition [NAME trapname]
dove:
SIGNAL ON inizia una subroutine di terminazione che chiude il programma
CALL ON inizia una subroutine di ritorno: l'elaborazione viene ripresa con la riga immediatamente successiva all'istruzione CALL ON.
Questa istruzione deve essere usata per recuperare l'esecuzione del programma dopo il verificarsi di un errore di comando o di sistema.
Le due condizioni che possono essere rilevate sono:
ERROR rileva un codice di ritorno diverso da zero restituito dall'ambiente di default come risultato di un comando REXX.
FAILURE rileva un serio errore che impedisce al sistema di elaborare un comando.
Per FAILURE, quindi, si intende una particolare categoria di errori.
Usando SIGNAL ON o CALL ON per la rilevazione solo di condizioni ERROR, si ottiene la rilevazione sia di condizioni di ERROR che di FAILURE. Se viene specificata anche una condizione di FAILURE allora la condizione di ERROR ignora il rilevamento di FAILURE.

Opzionalmente è possibile usare la parola chiave NAME per specificare una particolare subroutine da eseguire quando viene rilevata una condizione di ERROR o FAILURE.

Se il trap è specificato tramite NAME, il REXX salta alla riga di codice successiva all'etichetta specificata.
Se non viene specificato alcun NAME nell'istruzione SIGNAL ON o CALL ON, il REXX cerca un'etichetta appropriata alla condizione (ERROR: o FAILURE:).

Questo argomento verrà approfondito ulteriormente in seguito.

Disabilitazione dei trap
Per disabilitare la rilevazione degli errori in una qualsiasi parte del programma si usa la stessa istruzione seguita dalla parola chiave OFF:

SIGNAL OFF ERROR
SIGNAL OFF FAILURE
CALL OFF ERROR
CALL OFF FAILURE

Uso di SIGNAL ON ERROR
Questo è un esempio di come un programma potrebbe usare SIGNAL ON per rilevare un errore in un programma che copia un file.
Supponendo che nella variabile file1 sia memorizzato il nome di un file che non esiste, dalla riga

"COPY" file1 file2
l'esecuzione passa direttamente alle righe successive all'etichetta error:.
        /* esempio di "error trap" */
        signal on error                 /* Stabilisce il trap           */
             .
             .
             .
   +--<-"COPY"  file1 file2             /* se si verifica un errore ... */
   |         .
   |         .
   |    exit .
   +--->error:                           /* ...salta all'etichetta      */
        say "Errore" rc "alla linea" sigl
        say "Il programma non può continuare."
        exit                             /* e termina il programma      */

Uso di CALL ON ERROR
Se c'è un modo di ovviare all'errore, come, nel caso dell'esempio precedente, introducendo un nuovo nome di file, si deve usare CALL ON trap come mostrato nel seguente esempio:

         /* esempio di ripristino da una condizione di errore */
         call on error
              .
              .
              .
   +--<- "COPY"  file1 file2
   |     say file2 "in uso" -<---------------+
   |          .                              |
   |          .                              |
   |           exit                          |
   +---> error:                              |
         say "Impossibile trovare" file1     |
         say "Premere S per continuare."     |
         pull ans                            |
         if ans = "S" then                   |
            do                               |
               /* crea un nuovo file */      |
                    .                        |
                    .                        |
                    .                        |
               file2 = "dummy.fil"           |
               RETURN ->---------------------+
               end
         else exit

Esempio di routine per la gestione degli errori
Questa routine di gestione degli errori si può usare in molti programmi:

/* SIGERR.CMD: esempio di gestione degli errori               */
signal on error        /* abilita il rilevamento degli errori */
"ersae myfiles.*"      /* istruzione ERASE scritta scorretta  */
exit

/* questa è una routine generica di gestione degli errori     */
error:
  say "Errore" rc "in una chiamata di sistema."
  say
  say "numero riga =" sigl
  say "istruzione = " || sourceline(sigl)
  exit

Il programma PMREXX
Oltre che dalla riga di comando è possibile eseguire programmi REXX, tramite il programma PMREXX, in una finestra Presentation Manager.
Il programma PMREXX fornisce:

  • una finestra per l'output da:
    • L'istruzione SAY
    • Output normale e messaggi di errore dei comandi OS/2
    • L'output generato dall'istruzione TRACE.
  • una finestra per l'input per:
    • Le istruzioni PULL e PARSE PULL
    • L'immissione per programmi e comandi OS/2
  • possibilità di usare la clipboard e scrollare l'output dei programmi REXX e dei comandi OS/2
  • possibilità di selezionare il font preferito
  • opzioni per debuggare il programma REXX tramite l'istruzione TRACE o per terminarlo

L'uso del programma PMREXX è semplice. Per una singola istruzione basta digitare dalla riga di comando, per esempio:

PMREXX rexxtry say "Ciao programmatore!"
PMREXX mostrerà "Ciao programmatore!" in una finestra PM, poi farà apparire una finestra di dialogo per notificare che il programma REXX è terminato.
Un semplice programma REXX per mostrare il contenuto delle directory:
/* REXXDIR.CMD */
'@echo off'
Do Forever
  Say "Introdurre il nome di un file o directory"
  Parse Pull filename
  If filename = ""
    Then Leave
  "dir" filename
End
Per provare il programma digitate al prompt:
PMREXX [PATH\]REXXDIR
specificando al posto di [PATH\] il path in cui è collocato REXXDIR.CMD se questo non si trova nella directory corrente o in una delle directory incluse nella direttiva PATH del CONFIG.SYS.
Nella finestra inferiore del PMREXX verrà mostrato:
Introdurre il nome di un file o directory
nella finestra superiore del PMREXX si dovrà digitare il nome del file o della directory, premendo poi INVIO. Se si preme INVIO senza scrivere alcun nome il programma termina.
Le barre di scorrimento possono essere usate per poter visualizzare le precedenti linee non più visibili.
La finestra del PMREXX può essere ridimensionata o posizionata a piacere e tramite il menu si può scegliere se salvare quanto è nella finestra del programma su file, selezionare, copiare, tagliare, incollare, cancellare parte del testo mostrato, eseguire il programma REXX interattivamente un'istruzione per volta, cambiare il font usato dal programma, ecc..

La funzione RxMessageBox
Quando si esegue un programma REXX tramite PMREXX è possibile usare la funzione RxMessageBox per mostrare messaggi in una finestra di dialogo contente alcuni pulsanti. Per esempio:

/* ERROR.CMD : controlla il parametro introdotto */
arg count
if datatype(count, 'Whole') = 0 then do
   call RxMessageBox "Il parametro" count "non è un numero intero!"
   exit
end
Scrivendo da riga di comando:
PMREXX ERROR 3.5
otterremo una finestra di dialogo con la scritta "Il parametro 3.5 non è un numero intero" che potremo chiudere cliccando sul pulsante OK.

Oltre a poter mostrare qualsiasi messaggio, tramite RxMessageBox possiamo utilizzare diversi pulsanti e icone:

/* FILECHK.CMD: controlla l'esistenza di un file */
arg file
if stream(file, 'Command', "Query Exists") <> ''
   then do
      reply = RxMessageBox("Vuoi leggere il file" file"",,
         "Confermi?", "YesNo", "Question")
      if reply = 7 then exit         /* se l'utente preme NO */
   end
"@e" file                            /* apre file con e.exe  */
exit
Scrivendo da riga di comando ad esempio:
PMREXX FILECHK C:\CONFIG.SYS
se il file C:\CONFIG.SYS è presente sul disco, verrà mostrata una finestra di dialogo con Confermi? come titolo, un icona con un punto interrogativo e due pulsanti Yes e No.
Se si clicca sul pulsante Yes la funzione restituirà un valore pari a 6, mentre cliccando sul No si otterrà 7.
Maggiori informazioni sull'uso di RxMessageBox sono contenuto nella documentazione relativa al REXX inclusa nel sistema operativo.

L'opzione TRACE del PMREXX
Tramite l'opzione TRACE, che si attiva scrivendo /T tra il comando PMREXX e il nome del file CMD da eseguire, viene attivata l'esecuzione interattiva dello script REXX.

E' anche possibile attivare o disattivare il tracing successivamente dal menu Opzioni.


[Pagina precedente] [Sommario] [Pagina successiva]