Successivo: , Precedente: , Su: Funzioni di tipo generale   [Contenuti][Indice]


10.2.2 Asserzioni

Quando si scrivono grossi programmi, spesso è utile sapere se una condizione o una serie di condizioni è verificata oppure no. Prima di procedere con un determinato calcolo, si fa un’affermazione su cosa si crede sia vero. Tale affermazione è nota come asserzione. Il linguaggio C fornisce un file di intestazione <assert.h> e una corrispondente macro assert() che un programmatore può utilizzare per fare asserzioni. Se l’asserzione risulta falsa, la macro assert() predispone la stampa di un messaggio diagnostico che descrive la condizione che sarebbe dovuta essere vera ma che non lo era, e poi fa terminare il programma. In C, l’uso di assert() è simile a questo:

#include <assert.h>

int myfunc(int a, double b)
{
     assert(a <= 5 && b >= 17.1);
     …
}

Se l’asserzione è falsa, il programma stampa un messaggio simile a questo:

prog.c:5: asserzione falsa: `a <= 5 && b >= 17.1'

Il linguaggio C rende possibile trasformare questa condizione in una stringa da usare per stampare il messaggio di diagnosi. Ciò in awk non è possibile, per cui la funzione assert() scritta in awk richiede anche una descrizione della condizione da verificare, in formato stringa. La funzione è la seguente:

# assert --- Verifica una condizione. Se questa è falsa esce.

function assert(condizione, stringa)
{
    if (! condizione) {
        printf("%s:%d: asserzione falsa: %s\n",
            FILENAME, FNR, stringa) > "/dev/stderr"
        _assert_exit = 1
        exit 1
    }
}

END {
    if (_assert_exit)
        exit 1
}

La funzione assert() verifica il parametro condizione. Se è falso, stampa un messaggio sullo standard error, usando il parametro stringa per descrivere la condizione non verificata. Poi imposta la variabile _assert_exit a uno ed esegue l’istruzione exit. L’istruzione exit salta alla regola END. Se la regola END trova vera la variabile _assert_exit, esce immediatamente.

Lo scopo della verifica nella regola END è quello di evitare che venga eseguita qualsiasi altra eventuale regola END. Quando un’asserzione non è verificata, il programma dovrebbe uscire immediatamente. Se nessuna asserzione fallisce, _assert_exit è ancora falso quando la regola END è eseguita normalmente, e le eventuali altre regole END del programma vengono eseguite. Affinché tutto questo funzioni correttamente, assert.awk dev’essere il primo file sorgente che viene letto da awk. La funzione può essere usata in un programma nel seguente modo:

function miafunz(a, b)
{
     assert(a <= 5 && b >= 17.1, "a <= 5 && b >= 17.1")
     …
}

Se l’asserzione non è verificata, si vedrà un messaggio simile a questo:

mydata:1357: asserzione falsa: a <= 5 && b >= 17.1

C’è un piccolo problema con questa versione di assert(). Come visto, una regola END viene automaticamente aggiunta al programma che chiama assert(). Normalmente, se un programma consiste solo di una regola BEGIN, i file in input e/o lo standard input non vengono letti. Tuttavia, ora che il programma ha una regola END, awk tenta di leggere i file-dati in input o lo standard input (vedi la sezione Azioni di inizializzazione e pulizia), provocando molto probabilmente la sospensione del programma come se rimanesse in attesa di input.

C’è un modo per aggirare questo problema: assicurarsi che la regola BEGIN termini sempre con un’istruzione exit.


Successivo: , Precedente: , Su: Funzioni di tipo generale   [Contenuti][Indice]