Successivo: , Precedente: , Su: Programmi vari   [Contenuti][Indice]


11.3.2 Un programma di sveglia

Nessuna cura contro l’insonnia è efficace quanto una sveglia che suona.

Arnold Robbins

Il sonno è per sviluppatori web.

Erik Quanstrom

Il seguente programma è un semplice programma di “sveglia”. Si può specificare un’ora del giorno e un messaggio opzionale. All’ora specificata, il programma stampa il messaggio sullo standard output. Inoltre, si può specificare il numero di volte in cui il messaggio va ripetuto, e anche un intervallo di tempo (ritardo) tra ogni ripetizione.

Questo programma usa la funzione getlocaltime() da Gestione dell’ora del giorno.

Tutto il lavoro è svolto nella regola BEGIN. La prima parte è il controllo degli argomenti e l’impostazione dei valori di default: l’intervallo prima di ripetere, il contatore, e il messaggio da stampare. Se l’utente ha fornito un messaggio che non contiene il carattere ASCII BEL (noto come carattere “campanello”, "\a"), questo viene aggiunto al messaggio. (Su molti sistemi, stampare il carattere ASCII BEL genera un suono udibile. Quindi, quando la sveglia suona, il sistema richiama l’attenzione su di sé nel caso che l’utente non stia guardando il computer.) Per amor di varietà, questo programma usa un’istruzione switch (vedi la sezione L’istruzione switch), ma l’elaborazione potrebbe anche essere fatta con una serie di istruzioni if-else. Ecco il programma:

# alarm.awk --- impostare una sveglia
#
# Richiede la funzione di libreria getlocaltime()
# sintassi: alarm a_che_ora [ "messaggio" [ contatore [ ritardo ] ] ]

BEGIN {
    # Controllo iniziale congruità argomenti
    sintassi1 = "sintassi: alarm a_che_ora ['messaggio' [contatore [ritardo]]]"
    sintassi2 = sprintf("\t(%s) formato ora: ::= hh:mm", ARGV[1])

    if (ARGC < 2) {
        print sintassi1 > "/dev/stderr"
        print sintassi2 > "/dev/stderr"
        exit 1
    }
    switch (ARGC) {
    case 5:
        ritardo = ARGV[4] + 0
        # vai al caso seguente
    case 4:
        contatore = ARGV[3] + 0
        # vai al caso seguente
    case 3:
        messaggio = ARGV[2]
        break
    default:
        if (ARGV[1] !~ /[[:digit:]]?[[:digit:]]:[[:digit:]]{2}/) {
            print sintassi1 > "/dev/stderr"
            print sintassi2 > "/dev/stderr"
            exit 1
        }
        break
    }

    # imposta i valori di default per quando arriva l'ora desiderata
    if (ritardo == 0)
        ritardo = 180    # 3 minuti
    if (contatore == 0)
        contatore = 5
    if (messaggio == "")
        messaggio = sprintf("\aAdesso sono le %s!\a", ARGV[1])
    else if (index(message, "\a") == 0)
        messaggio = "\a" messaggio "\a"

La successiva sezione di codice scompone l’ora specificata in ore e minuti, la converte (se è il caso) al formato 24-ore, e poi calcola il relativo numero di secondi dalla mezzanotte. Poi trasforma l’ora corrente in un contatore dei secondi dalla mezzanotte. La differenza tra i due è il tempo di attesa che deve passare prima di far scattare la sveglia:

    # scomponi ora della sveglia
    split(ARGV[1], ore_minuti, ":")
    ora = ore_minuti[1] + 0     # trasforma in numero
    minuto = ore_minuti[2] + 0  # trasforma in numero

    # ottiene ora corrente divisa in campi
    getlocaltime(adesso)

    # se l'ora desiderata è in formato 12-ore ed è nel pomeriggio
    # (p.es., impostare `alarm 5:30' alle 9 del mattino
    # vuol dire far suonare la sveglia alle 5:30 pomeridiane)
    # aggiungere 12 all'ora richiesta
    if (hour < 12 && adesso["hour"] > ora)
        ora += 12

    # imposta l'ora in secondi dalla mezzanotte
    sveglia = (ora * 60 * 60) + (minuto * 60)

    # ottieni l'ora corrente in secondi dalla mezzanotte
    corrente = (now["hour"] * 60 * 60) + \
               (now["minute"] * 60) + now["second"]

    # quanto restare appisolati
    sonno = sveglia - corrente
    if (sonno <= 0) {
        print "alarm: l'ora è nel passato!" > "/dev/stderr"
        exit 1
    }

Infine, il programma usa la funzione system() (vedi la sezione Funzioni di Input/Output) per chiamare il programma di utilità sleep. Il programma di utilità sleep non fa altro che aspettare per il numero di secondi specificato. Se il codice di ritorno restituito è diverso da zero, il programma suppone che sleep sia stato interrotto ed esce. Se sleep è terminato con un codice di ritorno corretto, (zero), il programma stampa il messaggio in un ciclo, utilizzando ancora sleep per ritardare per il numero di secondi necessario:

    # zzzzzz..... esci se sleep è interrotto
    if (system(sprintf("sleep %d", sonno)) != 0)
        exit 1

    # è ora di avvisare!
    command = sprintf("sleep %d", ritardo)
    for (i = 1; i <= contatore; i++) {
        print messaggio
        # se il comando sleep è interrotto, esci
        if (system(command) != 0)
            break
    }

    exit 0
}

Successivo: , Precedente: , Su: Programmi vari   [Contenuti][Indice]