diff options
Diffstat (limited to 'doc/it/gawktexi.in')
-rw-r--r-- | doc/it/gawktexi.in | 45878 |
1 files changed, 45878 insertions, 0 deletions
diff --git a/doc/it/gawktexi.in b/doc/it/gawktexi.in new file mode 100644 index 00000000..678125e7 --- /dev/null +++ b/doc/it/gawktexi.in @@ -0,0 +1,45878 @@ +\language=30 +\input texinfo @c -*-texinfo-*- +@c vim: filetype=texinfo +@c %**start of header (This is for running Texinfo on a region.) +@setfilename gawk-it.info +@settitle Guida Utente di GNU Awk +@documentlanguage it +@c %**end of header (This is for running Texinfo on a region.) + +@dircategory Creazione e manipolazione di testi +@direntry +* Gawk: (gawk). Un linguaggio per scandire ed elaborare testi. +@end direntry +@dircategory Programmi di utilit@`a individuale +@direntry +* awk: (gawk)Avviare gawk. Scansione e processo di testi. +@end direntry + +@c Enable better indexing, requires texindex from Texinfo 6 or later. +@tex +\global\usebracesinindexestrue +@end tex + +@ifset FOR_PRINT +@tex +\gdef\xrefprintnodename#1{``#1''} +@end tex +@end ifset + +@ifclear FOR_PRINT +@c With early 2014 texinfo.tex, restore PDF links and colors +@tex +\gdef\linkcolor{0.5 0.09 0.12} % Dark Red +\gdef\urlcolor{0.5 0.09 0.12} % Also +\global\urefurlonlylinktrue +@end tex +@end ifclear + +@ifnotdocbook +@set BULLET @bullet{} +@set MINUS @minus{} +@end ifnotdocbook + +@ifdocbook +@set BULLET +@set MINUS +@end ifdocbook + +@set xref-automatic-section-title + +@c The following information should be updated here only! +@c This sets the edition of the document, the version of gawk it +@c applies to and all the info about who's publishing this edition + +@c These apply across the board. +@c Aggiornata alla versione del 3 marzo 2017 +@set UPDATE-MONTH gennaio 2017 +@set VERSION 4.1 +@set PATCHLEVEL 4 + +@c added Italian hyphenation stuff +@hyphenation{ven-go-no o-met-te-re o-met-ten-do} + +@set GAWKINETTITLE TCP/IP Internetworking with @command{gawk} +@ifset FOR_PRINT +@set TITLE Programmare efficacemente in awk +@end ifset +@ifclear FOR_PRINT +@set TITLE GAWK: Programmare efficacemente in AWK +@end ifclear +@set SUBTITLE Una Guida Utente per GNU Awk +@set EDITION 4.1 + +@iftex +@set DOCUMENT libro +@set CHAPTER capitolo +@set APPENDIX appendice +@set SECTION sezione +@set SECTIONS sezioni +@set SUBSECTION sottosezione +@ifclear SMALLPRINT +@set DARKCORNER @inmargin{@image{lflashlight,1cm}, @image{rflashlight,1cm}} +@end ifclear +@ifset SMALLPRINT +@set DARKCORNER @inmargin{@image{lflashlight,0.7cm}, @image{rflashlight,0.7cm}} +@end ifset +@set COMMONEXT (e.c.) +@set PAGE pagina +@end iftex +@ifinfo +@set DOCUMENT File Info +@set CHAPTER nodo principale +@set APPENDIX nodo principale +@set SECTION nodo secondario +@set SECTIONS nodi secondari +@set SUBSECTION nodo +@set DARKCORNER (a.b.) +@set COMMONEXT (e.c.) +@set PAGE videata +@end ifinfo +@ifhtml +@set DOCUMENT Documento +@set CHAPTER capitolo +@set APPENDIX appendice +@set SECTION sezione +@set SECTIONS sezioni +@set SUBSECTION sottosezione +@set DARKCORNER (a.b.) +@set COMMONEXT (e.c.) +@set PAGE videata +@end ifhtml +@ifdocbook +@set DOCUMENT libro +@set CHAPTER capitolo +@set APPENDIX appendice +@set SECTION sezione +@set SECTIONS sezioni +@set SUBSECTION sottosezione +@set DARKCORNER (a.b.) +@set COMMONEXT (e.c.) +@set PAGE pagina +@end ifdocbook +@ifxml +@set DOCUMENT libro +@set CHAPTER capitolo +@set APPENDIX appendice +@set SECTION sezione +@set SECTIONS sezioni +@set SUBSECTION sottosezione +@set DARKCORNER (a.b.) +@set COMMONEXT (e.c.) +@set PAGE pagina +@end ifxml +@ifplaintext +@set DOCUMENT libro +@set CHAPTER capitolo +@set APPENDIX appendice +@set SECTION sezione +@set SECTIONS sezioni +@set SUBSECTION sottosezione +@set DARKCORNER (a.b.) +@set COMMONEXT (e.c.) +@set PAGE pagina +@end ifplaintext + +@ifdocbook +@c empty on purpose +@set PART1 +@set PART2 +@set PART3 +@set PART4 +@end ifdocbook + +@ifnotdocbook +@set PART1 Parte I:@* +@set PART2 Parte II:@* +@set PART3 Parte III:@* +@set PART4 Parte IV:@* +@end ifnotdocbook + +@c some special symbols +@iftex +@set LEQ @math{@leq} +@set PI @math{@pi} +@end iftex +@ifdocbook +@set LEQ @inlineraw{docbook, ≤} +@set PI @inlineraw{docbook, &pgr;} +@end ifdocbook +@ifnottex +@ifnotdocbook +@set LEQ <= +@set PI @i{pi} +@end ifnotdocbook +@end ifnottex + +@ifnottex +@ifnotdocbook +@macro ii{text} +@i{\text\} +@end macro +@end ifnotdocbook +@end ifnottex + +@ifdocbook +@macro ii{text} +@inlineraw{docbook,<lineannotation>\text\</lineannotation>} +@end macro +@end ifdocbook + +@ifclear FOR_PRINT +@set FN nome-file +@set FFN Nome-file +@c for Italian plurals {FN}s +@set FNS nomi-file +@set FFNS Nomi-file +@set DF file-dati +@set DDF File-dati +@set PVERSION versione +@end ifclear +@ifset FOR_PRINT +@set FN nome-file +@set FFN Nome-File +@c for Italian plurals {FN}s +@set FNS nomi-file +@set FFNS Nomi-file +@set DF file-dati +@set DDF File-dati +@set PVERSION Versione +@end ifset + +@c For HTML, spell out email addresses, to avoid problems with +@c address harvesters for spammers. +@ifhtml +@macro EMAIL{real,spelled} +``\spelled\'' +@end macro +@end ifhtml +@ifnothtml +@macro EMAIL{real,spelled} +@email{\real\} +@end macro +@end ifnothtml + +@c Indexing macros +@ifinfo + +@macro cindexawkfunc{name} +@cindex @code{\name\} +@end macro + +@macro cindexgawkfunc{name} +@cindex @code{\name\} +@end macro + +@end ifinfo + +@ifnotinfo + +@macro cindexawkfunc{name} +@cindex @code{\name\()}, funzione +@end macro + +@macro cindexgawkfunc{name} +@cindex @code{\name\()}, funzione (@command{gawk}) +@end macro +@end ifnotinfo + +@ignore +Some comments on the layout for TeX. +1. Use at least texinfo.tex 2016-02-05.07. +@end ignore + +@c merge the function and variable indexes into the concept index +@ifinfo +@synindex fn cp +@synindex vr cp +@end ifinfo +@iftex +@syncodeindex fn cp +@syncodeindex vr cp +@end iftex +@ifxml +@syncodeindex fn cp +@syncodeindex vr cp +@end ifxml +@ifdocbook +@synindex fn cp +@synindex vr cp +@end ifdocbook + +@c If "finalout" is commented out, the printed output will show +@c black boxes that mark lines that are too long. Thus, it is +@c unwise to comment it out when running a master in case there are +@c overfulls which are deemed okay. + +@iftex +@finalout +@end iftex + +@copying +@docbook +<para> +“To boldly go where no man has gone before” +(“Per arrivare l@`a dove nessun uomo @`e mai giunto prima”) +@`e un Marchio Registrato della Paramount Pictures Corporation.</para> + +<para>Titolo originale:</para> +@b{Gawk: Effective AWK Programming}@* +@i{A User's Guide for GNU Awk} + +<para>Published by:</para> +<literallayout class="normal">Free Software Foundation +51 Franklin Street, Fifth Floor -- Boston, MA 02110-1301 USA +Tel.: +1-617-542-5942 Fax: +1-617-542-2652 Email: <email>gnu@@gnu.org</email> +URL: <ulink url="http://www.gnu.org">http://www.gnu.org/</ulink></literallayout> + +<literallayout class="normal">Copyright © 1989, 1991, 1992, 1993, 1996–2005, 2007, 2009–2017 +Free Software Foundation, Inc. +All Rights Reserved. +</literallayout> + +</para>Traduzione e revisione:<para> +<literallayout class="normal"> +Antonio Giovanni Colombo -- <email>azc100(chiocciola)gmail(punto)com</email> +Marco Curreli -- <email>marcocurreli(chiocciola)tiscali(punto)it</email> +(Italian Linux Documentation Project (<ulink url="http://www.pluto.it/ildp">http://www.pluto.it/ildp/</ulink>) +</literallayout> + +<para>Pubblicato da:</para> +<literallayout class="normal">Free Software Foundation +Email: <email>gnu@@gnu.org</email> +URL: <ulink url="http://www.gnu.org">http://www.gnu.org/</ulink> + +e da: +Italian Linux Documentation Project (ILDP) +Email: <emailildp@@pluto.it +URL: <ulink url="http://www.pluto.it/ildp">http://www.pluto.it/ildp/</ulink></literallayout> + +<literallayout class="normal">Copyright © 2016 +Free Software Foundation, Inc. +All Rights Reserved. +</literallayout> +@end docbook + +@ifnotdocbook +@iftex +Copyright @copyright{} 2017 -- Free Software Foundation, Inc. +@end iftex +@end ifnotdocbook +@sp 2 +Questa @`e l'Edizione @value{EDITION} di @cite{@value{TITLE}: @value{SUBTITLE}}, +per la versione @value{VERSION}.@value{PATCHLEVEL} (o successiva) +dell'implementazione GNU di AWK. +@ifnottex +@ifnotxml +@ifnotdocbook +(Titolo originale: @i{Gawk: Effective AWK Programming: A User's Guide for GNU Awk.)} +@end ifnotdocbook +@end ifnotxml +@end ifnottex + +@`E garantito il permesso di copiare, distribuire e/o modificare questo +documento seguendo i termini della Licenza per Documentazione Libera +GNU, Versione 1.3 o ogni versione successiva pubblicata dalla Free +Software Foundation; con le Sezioni Non Modificabili ``GNU General +Public License'', con i testi di copertina ``Un Manuale GNU'', e con i +testi di quarta di copertina come in (a) pi@`u avanti. +@ifclear FOR_PRINT +Una copia della licenza @`e acclusa nella sezione intitolata +"Licenza per Documentazione Libera GNU". +@end ifclear +@ifset FOR_PRINT +Una copia della licenza +si pu@`o trovare in internet all'indirizzo +@uref{http://www.gnu.org/software/gawk/manual/html_node/GNU-Free-Documentation-License.html, +il sito web del Progetto GNU}. +@end ifset + +@enumerate a +@item +Il testo di quarta di copertina della FSF @`e: ``@`E garantito il permesso di +copiare e modificare questo manuale GNU.'' +@end enumerate +@end copying + +@c Comment out the "smallbook" for technical review. Saves +@c considerable paper. Remember to turn it back on *before* +@c starting the page-breaking work. + +@c 4/2002: Karl Berry recommends commenting out this and the +@c `@setchapternewpage odd', and letting users use `texi2dvi -t' +@c if they want to waste paper. +@c @smallbook + + +@c Uncomment this for the release. Leaving it off saves paper +@c during editing and review. +@setchapternewpage odd + +@shorttitlepage GNU Awk +@titlepage +@title @value{TITLE} +@subtitle @value{SUBTITLE} +@subtitle Edizione @value{EDITION} +@subtitle @value{UPDATE-MONTH} +@author Arnold D. Robbins + +@ifnotdocbook +@c Include the Distribution inside the titlepage environment so +@c that headings are turned off. Headings on and off do not work. + +@page +@vskip 0pt plus 1filll +``To boldly go where no man has gone before'' +(``Per arrivare l@`a dove nessun uomo @`e mai giunto prima'') +@`e un Marchio Registrato della Paramount Pictures Corporation. @* +@c sorry, i couldn't resist +@sp 1 +Titolo originale:@* +@b{Gawk: Effective AWK Programming}@* +@i{A User's Guide for GNU Awk} +@sp 0 +Published by @strong{Free Software Foundation}@* +51 Franklin Street, Fifth Floor -- Boston, MA 02110-1301 USA @* +Tel.: +1-617-542-5942 -- Fax: +1-617-542-2652 -- Email: @email{gnu@@gnu.org} @* +URL: @uref{http://www.gnu.org/} +@sp 0 +@c This one is correct for gawk 3.1.0 from the FSF +ISBN 1-882114-28-0 +@sp 0 +Copyright @copyright{} 1989, 1991, 1992, 1993, 1996--2005, 2007, 2009--2017 @* +Free Software Foundation, Inc. +@sp 1 +Traduzione e revisione:@* +Antonio Giovanni Colombo -- @email{azc100(chiocciola)gmail(punto)com}@* +Marco Curreli -- @email{marcocurreli(chiocciola)tiscali(punto)it}@* +(Italian Linux Documentation Project -- @uref{http://www.pluto.it/ildp}) +@sp 1 +Pubblicato da: +Free Software Foundation@* +Email: @email{gnu@@gnu.org}; URL: @uref{http://www.gnu.org/} + +e da: +Italian Linux Documentation Project (ILDP)@* +Email: @email{ildp@@pluto.it}; URL: @uref{http://www.pluto.it/ildp} + +@insertcopying +@sp 1 +@end ifnotdocbook +@end titlepage + +@c Thanks to Bob Chassell for directions on doing dedications. +@iftex +@headings off +@page +@w{ } +@sp 9 + +@ifclear SMALLPRINT +@center @i{Ai miei genitori, per il loro amore, e per lo splendido esempio che mi hanno dato.} +@sp 1 +@center @i{A mia moglie, Miriam, per avermi reso completo. +Grazie per aver costruito la tua vita insieme a me.} +@sp 1 +@center @i{Ai nostri figli, Chana, Rivka, Nachum e Malka, per aver arricchito le nostre vite in misura incalcolabile.} +@end ifclear + +@ifset SMALLPRINT +@center @i{Ai miei genitori, per il loro amore,} +@center @i{ e per lo splendido esempio che mi hanno dato.} +@sp 1 +@center @i{A mia moglie, Miriam, per avermi reso completo.} @* +@center @i{ Grazie per aver costruito la tua vita insieme a me.} +@sp 1 +@center @i{Ai nostri figli, Chana, Rivka, Nachum e Malka,} +@center @i{per aver arricchito le nostre vite in misura incalcolabile.} +@end ifset + +@sp 1 +@w{ } +@page +@w{ } +@page +@headings on +@end iftex + +@docbook +<dedication> +<para>Ai miei genitori, per il loro amore, e per lo splendido +esempio che mi hanno dato.</para> +<para>A mia moglie Miriam, per avermi reso completo. +Grazie per aver costruito la tua vita insieme con me.</para> +<para>Ai nostri figli Chana, Rivka, Nachum e Malka, +per aver arricchito le nostre vite in misura incalcolabile.</para> +</dedication> +@end docbook + +@iftex +@headings off +@evenheading @thispage@ @ @ @strong{@value{TITLE}} @| @| +@oddheading @| @| @strong{@thischapter}@ @ @ @thispage +@end iftex + +@ifnottex +@ifnotxml +@ifnotdocbook +@node Top +@top Introduzione Generale +@c Preface node should come right after the Top +@c node, in `unnumbered' sections, then the chapter, `What is gawk'. +@c Licensing nodes are appendices, they're not central to AWK. + +Questo file documenta @command{awk}, un programma che si pu@`o usare per +selezionare dei record determinati in un file ed eseguire azioni su di essi. + +@noindent +Copyright dell'edizione originale @copyright{} 1989, 1991, 1992, 1993, 1996--2005, 2007, 2009--2017 @* +Free Software Foundation, Inc. + +@noindent +Copyright dell'edizione italiana @copyright{} 2016 -- Free Software Foundation, Inc. + + +@insertcopying + +@end ifnotdocbook +@end ifnotxml +@end ifnottex + +@menu +* Introduzione3:: Alcune parole gentili riguardo a questo + @value{DOCUMENT}. +* Introduzione4:: Ulteriori parole gentili. +* Prefazione:: Di cosa tratta questo @value{DOCUMENT}; + breve storia e ringraziamenti. +* Per iniziare:: Un'introduzione elementare all'uso di + @command{awk}. Come eseguire un programma + @command{awk}. Sintassi della riga di + comando. +* Invocare Gawk:: Come eseguire @command{gawk}. +* Espressioni regolari:: Tutto quel che c'@`e da sapere + sull'individuazione di stringhe tramite + espressioni regolari. +* Leggere file:: Come leggere file e manipolare campi. +* Stampare:: Come stampare usando @command{awk}. + Descrizione delle istruzioni @code{print} e + @code{printf}. @`E descritta inoltre la + ridirezione dell'output. +* Espressioni:: Le espressioni sono i componenti elementari + delle istruzioni. +* Criteri di ricerca e azioni:: Panoramica sui criteri di ricerca e sulle + azioni. +* Vettori:: La descrizione e l'uso dei vettori. Sono + inoltre descritte le istruzioni di controllo + relative ai vettori. +* Funzioni:: Funzioni predefinite e definite dall'utente. +* Funzioni di libreria:: Una libreria di funzioni di @command{awk}. +* Programmi di esempio:: Molti programmi @command{awk} con + spiegazioni dettagliate. +* Funzionalit@`a avanzate:: Roba per utenti sofisticati, propria di + @command{gawk}. +* Internazionalizzazione:: Come far s@`{@dotless{i}} che @command{gawk} parli la + vostra lingua. +* Debugger:: Il debugger di @command{gawk}. +* Calcolo con precisione arbitraria:: Calcolo con precisione arbitraria in + @command{gawk}. +* Estensioni dinamiche:: Aggiungere nuove funzioni predefinite di + @command{gawk}. +* Storia del linguaggio:: L'evoluzione del linguaggio @command{awk}. +* Installazione:: Installare @command{gawk} in vari sistemi + operativi. +* Note:: Note riguardo ad aggiunte a @command{gawk} + e possibili futuri sviluppi. +* Concetti fondamentali:: Velocissima introduzione alla + programmazione. +* Glossario:: Spiegazione di alcuni termini poco + familiari. +* Copia:: Il vostro diritto a copiare e distribuire + @command{gawk}. +* Licenza per Documentazione Libera GNU (FDL):: La licenza per questo + @value{DOCUMENT}. +* Indice analitico:: Indice dei concetti e delle variabili. + +@detailmenu +* Storia:: La storia di @command{gawk} e + @command{awk}. +* Nomi:: Che nome usare per trovare + @command{awk}. +* Questo manuale:: Uso di questo @value{DOCUMENT}. + Comprende esempi di file in input + utilizzabili. +* Convenzioni:: Convenzioni tipografiche. +* Storia del manuale:: Breve storia del progetto GNU e di + questo @value{DOCUMENT}. +* Come contribuire:: Un aiuto per la salvezza del mondo. +* Ringraziamenti:: Ringraziamenti. +* Eseguire gawk:: Come eseguire programmi + @command{gawk}; comprende la sintassi + della riga di comando. +* Monouso:: Eseguire un breve programma + @command{awk} di tipo usa-e-getta. +* Leggere dal terminale:: Senza uso di file in input (input + immesso da tastiera). +* Lunghi:: Mettere programmi @command{awk} + permanenti in file. +* @dfn{Script} eseguibili:: Preparare programmi @command{awk} + da eseguire come @dfn{script}. +* Commenti:: Aggiungere documentazione a programmi + @command{gawk}. +* Protezione:: Ulteriore discussione di problemi + connessi alle protezioni nella shell. +* Doppi apici in DOS:: Doppi apici in file .BAT Windows +* File dati di esempio:: File di dati di esempio da usare nei + programmi @command{awk} illustrati in + questo @value{DOCUMENT}. +* Molto semplice:: Un esempio molto semplice. +* Due regole:: Un esempio meno semplice di programma + di una riga, che usa due regole. +* Maggiore sofisticazione:: Un esempio pi@`u complesso. +* Istruzioni/Righe:: Suddividere o riunire istruzioni + su [una o pi@`u] righe. +* Altre funzionalit@`a:: Altre funzionalit@`a di @command{awk}. +* Quando:: Quando usare @command{gawk} e quando + usare altre cose. +* Sommario dell'introduzione:: Sommario dell'introduzione. +* Riga di comando:: Come eseguire @command{awk}. +* Opzioni:: Opzioni sulla riga di comando e loro + significato. +* Altri argomenti:: Nomi dei file in input e assegnamento + di valori a variabili. +* Specificare lo standard input:: Come specificare lo standard input + insieme ad altri file. +* Variabili d'ambiente:: Le variabili d'ambiente usate da + @command{gawk}. +* AWKPATH (Variabile):: Ricerca di programmi @command{awk} + in una lista di directory. +* AWKLIBPATH (Variabile):: Ricerca di librerie condivise + @command{awk} in una lista di + directory. +* Altre variabili d'ambiente:: Le variabili d'ambiente. +* Codice di ritorno:: Il codice di ritorno all'uscita + da @command{gawk}. +* Includere file:: Come includere altri file nel + proprio programma. +* Caricare librerie condivise:: Caricare librerie condivise nel + proprio programma. +* Parti obsolete:: Opzioni e/o funzionalit@`a obsolete. +* Non documentato:: Opzioni e funzionalit@`a non documentate. +* Sommario invocazione:: Sommario di come eseguire + @command{awk}. +* Uso di @dfn{regexp}:: Come usare le espressioni regolari. +* Sequenze di protezione:: Come scrivere caratteri non stampabili. +* Operatori di espressioni regolari:: Operatori di espressioni regolari. +* Espressioni tra parentesi quadre:: Cosa possono contenere @samp{[...]}. +* Pi@`u lungo da sinistra:: Quanto @`e lungo il testo individuato. +* Espressioni regolari calcolate:: Usare @dfn{regexp} dinamiche. +* Operatori di @dfn{regexp} GNU:: Operatori propri del software GNU. +* Maiuscolo-Minuscolo:: Fare confronti ignorando + maiuscolo/minuscolo. +* Sommario espressioni regolari:: Sommario delle espressioni regolari. +* Record:: Controllare come i dati sono suddivisi + in record. +* awk divisione record:: Divisione dei record con @command{awk} + standard. +* gawk divisione record:: Divisione dei record con @command{gawk}. +* Campi:: Un'introduzione ai campi. +* Campi non costanti:: Numeri di campo variabili. +* Cambiare i campi:: Cambiare il contenuto di un campo. +* Separatori di campo:: I separatori di campo, e come + cambiarli. +* Separatori di campo di default:: Come di solito sono separati i campi. +* Separare campi con @dfn{regexp}:: Usare @dfn{regexp} come separatori. +* Campi di un solo carattere:: Fare di ogni carattere un campo + separato. +* Separatori campo da riga di comando:: Impostare @code{FS} dalla riga di + comando. +* Campo intera riga:: Fare di una riga intera un campo + solo. +* Sommario sulla separazione campi:: Alcuni punti finali e una tavola di + sommario. +* Dimensione costante:: Leggere campi di larghezza costante. +* Separazione in base al contenuto:: Definire campi dal loro Contenuto. +* Righe multiple:: Record su righe multiple +* Getline:: Richiedere input usando @code{getline}. +* Getline semplice:: Usare @code{getline} senza argomenti. +* Getline variabile:: Usare @code{getline} in una variabile. +* Getline file:: Usare @code{getline} da un file. +* Getline variabile file:: Usare @code{getline} in una variabile + da un file. +* Getline @dfn{pipe}:: Usare @code{getline} da una @dfn{pipe}. +* Getline variabile @dfn{pipe}:: Usare @code{getline} in una variabile + da una @dfn{pipe}. +* Getline coprocesso:: Usare @code{getline} da un coprocesso. +* Getline variabile coprocesso:: Usare @code{getline} in una variabile + da un coprocesso. +* Note su getline:: Cose importanti da sapere su + @code{getline}. +* Sommario di getline:: Sommario delle varianti di + @code{getline}. +* Timeout in lettura:: Leggere input entro un tempo limite. +* Proseguire dopo errore in input:: Rielaborare input dopo certi errori. +* Directory su riga di comando:: Cosa accade se si mette una directory + sulla riga di comando. +* Sommario di Input:: Sommario di Input. +* Esercizi su Input:: Esercizi. +* Print:: L'istruzione @code{print}. +* Esempi su print:: Semplici esempi di + istruzioni @code{print}. +* Separatori di output:: I separatori di output e come + modificarli. +* OFMT:: Controllare l'output di numeri con + @code{print}. +* Printf:: L'istruzione @code{printf}. +* Printf Fondamenti:: Sintassi dell'istruzione + @code{printf}. +* Lettere di controllo:: Lettere di controllo del formato. +* Modificatori di formato:: Modificatori specifiche di formato. +* Esempi su printf:: Numerosi esempi. +* Ridirezione:: Come ridirigere l'output a diversi + file e @dfn{pipe}. +* FD speciali:: File speciali per I/O. +* File speciali:: Interpretazione @value{FNS} in + @command{gawk}. @command{gawk} + permette di accedere a descrittori di + file ereditati. +* Altri file ereditati:: Accedere ad altri file aperti con + @command{gawk}. +* Reti speciali:: File speciali per comunicazioni con + la rete. +* Avvertimenti speciali:: Cose a cui prestare attenzione. +* Chiusura file e @dfn{pipe}:: Chiudere file in input e di output e + @dfn{pipe}. +* Continuazione dopo errori:: Abilitare continuazione dopo errori + in output. +* Sommario di Output:: Sommario di Output. +* Esercizi su Output:: Esercizi. +* Valori:: Costanti, variabili ed espressioni + regolari. +* Costanti:: Costanti di tipo stringa, numeriche ed + espressioni regolari. +* Costanti scalari:: Costanti numeriche e stringhe. +* Numeri non-decimali:: Cosa sono i numeri ottali ed + esadecimali. +* Costanti come espressioni regolari:: Costanti fornite tramite espressioni + regolari. +* Usare le costanti @dfn{regexp}:: Quando e come usare una costante + specificata tramite espressioni + regolari +* Costanti @dfn{regexp} normali:: Costanti @dfn{regexp} normali in + @command{awk}. +* Costanti @dfn{regexp} forti:: Costanti @dfn{regexp} fortemente + tipizzate. +* Variabili:: Le variabili permettono di + definire valori da usare in seguito. +* Usare variabili:: Usare variabili nei propri programmi. +* Opzioni di assegnamento:: Impostare variabili dalla riga di + comando, e un sommario della sintassi + della riga di comando. + Questo @`e un metodo di input avanzato. +* Conversione:: La conversione di stringhe in numeri + e viceversa. +* Stringhe e numeri:: Come @command{awk} converte tra + stringhe e numeri. +* Localizzazione e conversioni:: Come la localizzazione pu@`o influire + sulle conversioni. +* Tutti gli operatori:: Gli operatori di @command{gawk}. +* Operatori aritmetici:: Operazioni aritmetiche (@samp{+}, + @samp{-}, etc.) +* Concatenazione:: Concatenazione di stringhe. +* Operatori di assegnamento:: Cambiare il valore di una variabile + o di un campo. +* Operatori di incremento:: Incrementare il valore numerico di una + variabile. +* Valori e condizioni di verit@`a:: Determinare Vero/Falso. +* Valori di verit@`a:: Cosa @`e ``vero'' e cosa @`e ``falso''. +* Tipi di variabile e confronti:: Come alle variabili si assegna il tipo + e l'effetto che questo ha sul confronto + di numeri e stringhe con @samp{<}, etc. +* Tipi di variabile:: Tipo stringa rispetto a tipo numero. +* Operatori di confronto:: Gli operatori di confronto. +* Confronto POSIX di stringhe:: Confronto tra stringhe usando le + regole POSIX. +* Operatori booleani:: Combinare espressioni di confronto + usando operatori booleani @samp{||} + (``or''), @samp{&&} (``and'') e + @samp{!} (``not''). +* Espressioni condizionali:: Le espressioni condizionali scelgono + una tra due sottoespressioni, a + seconda del valore di una terza + sottoespressione. +* Chiamate di funzione:: Una chiamata di funzione @`e + un'espressione. +* Precedenza:: Come si nidificano i vari operatori. +* Localizzazioni:: Come la localizzazione influenza la + gestione dati. +* Sommario delle espressioni:: Sommario delle espressioni. +* Panoramica sui criteri di ricerca:: Come scrivere un criterio di ricerca. +* @dfn{regexp} come criteri di ricerca:: Espressioni regolari come criteri + di ricerca. +* Espressioni come criteri di ricerca:: Qualsiasi espressione pu@`o servire da + criterio di ricerca. +* Intervalli:: Specificare intervalli di record con i + criteri di ricerca. +* BEGIN/END:: Specificare regole di inizio e fine + programma. +* Usare BEGIN/END:: Come e perch@'e usare regole BEGIN/END. +* I/O e BEGIN/END:: Problemi di I/O nelle regole BEGIN/END. +* BEGINFILE/ENDFILE:: Due condizioni speciali per controlli + avanzati. +* Vuoto:: Il criterio di ricerca vuoto, che + corrisponde a ogni record. +* Usare variabili di shell:: Come usare variabili di shell in + @command{awk}. +* Panoramica sulle azioni:: Cosa costituisce un'azione. +* Istruzioni:: Descrizione dettagliata delle varie + istruzioni di controllo. +* Istruzione if:: Eseguire in maniera condizionale + istruzioni @command{awk}. +* Istruzione while:: Eseguire il ciclo, finch@'e @`e + verificata una condizione. +* Istruzione do:: Eseguire l'azione specificata, continuare + a eseguire il ciclo + finch@'e @`e verificata una condizione. +* Istruzione for:: Un'altra istruzione iterativa, che + permette di specificare clausole + iniziali e di incremento. +* Istruzione switch:: Valutazione di quale insieme di + istruzioni eseguire, a seconda del + valore assunto da una variabile. +* Istruzione break:: Uscire subito dal ciclo pi@`u interno + in cui ci si trova. +* Istruzione continue:: Andare alla fine del ciclo pi@`u interno + in cui ci si trova. +* Istruzione next:: Smettere di elaborare il record + corrente. +* Istruzione nextfile:: Smettere di elaborare il file + corrente. +* Istruzione exit:: Interrompere l'esecuzione di @command{awk}. +* Variabili predefinite:: Sommario delle variabili predefinite. +* Variabili modificabili dall'utente:: Variabili predefinite modificabili per + controllare @command{awk}. +* Variabili auto-assegnate:: Variabili predefinite con cui + @command{awk} fornisce informazioni. +* ARGC e ARGV:: Modi di usare @code{ARGC} e + @code{ARGV}. +* Sommario criteri e azioni:: Sommario criteri e azioni. +* Fondamenti sui vettori:: Informazioni di base sui vettori. +* Introduzione ai vettori:: Introduzione ai vettori. +* Visitare elementi:: Come esaminare un elemento di un + vettore. +* Impostare elementi:: Come cambiare un elemento di un + vettore. +* Esempio di vettore:: Esempio semplice di vettore +* Visitare un intero vettore:: Variazione dell'istruzione + @code{for}. Cicla attraverso gli + indici degli elementi contenuti in + un vettore. +* Controllare visita:: Controllare l'ordine in cui i vettori + sono visitati. +* Indici numerici di vettore:: Come usare numeri come indici in + @command{awk}. +* Indici non inizializzati:: Usare variabili non inizializzate + come indici. +* Cancellazione:: L'istruzione @code{delete} toglie un + elemento da un vettore. +* Vettori multidimensionali:: Emulare vettori multidimensionali in + @command{awk}. +* Visitare vettori multidimensionali:: Visitare vettori multidimensionali. +* Vettori di vettori:: Vettori multidimensionali veri. +* Sommario dei vettori:: Sommario dei vettori. +* Funzioni predefinite:: Riepilogo delle funzioni predefinite. +* Chiamare funzioni predefinite:: Come chiamare funzioni predefinite. +* Funzioni numeriche:: Funzioni che trattano numeri, comprese + @code{int()}, @code{sin()} + e @code{rand()}. +* Funzioni per stringhe:: Funzioni di manipolazione di stringhe, + come @code{split()}, @code{match()} + e @code{sprintf()}. +* Dettagli ostici:: Pi@`u di quel che si vorrebbe sapere su + @samp{\} e @samp{&} con @code{sub()}, + @code{gsub()}, e @code{gensub()}. +* Funzioni di I/O:: Funzioni per i file e per i comandi + della shell. +* Funzioni di tempo:: Funzione per gestire marcature temporali. +* Funzioni a livello di bit:: Funzioni per operazioni di + manipolazione bit. +* Funzioni per i tipi:: Funzioni per conoscere il tipo + di una variabile. +* Funzioni di internazionalizzazione:: Funzioni per tradurre stringhe. +* Funzioni definite dall'utente:: Descrizione dettagliata delle funzioni + definite dall'utente. +* Sintassi delle definizioni:: Come scrivere definizioni e cosa + significano. +* Esempio di funzione:: Un esempio di definizione di + funzione e spiegazione della stessa. +* Precisazioni sulle funzioni:: Cose a cui prestare attenzione. +* Chiamare una funzione:: Non usare spazi. +* Campo di validit@`a variabili:: Variabili locali e globali. +* Parametri per valore/riferimento:: Passaggio parametri. +* Istruzione return:: Specificare il valore che una + funzione restituisce. +* Variabili di tipo dinamico:: Come cambiare tipo a una variabile in + fase di esecuzione del programma. +* Chiamate indirette:: Scegliere la funzione da chiamare in + fase di esecuzione del programma. +* Sommario delle funzioni:: Sommario delle funzioni. +* Nomi di variabili di libreria:: Che nomi @`e meglio dare alle variabili + private globali nelle funzioni di + libreria +* Funzioni di tipo generale:: Funzioni di uso generale. +* Funzione strtonum:: Da usare se non @`e disponibile la + funzione predefinita + @code{strtonum()}. +* Funzione assert:: Una funzione per controllare + affermazioni in programmi + @command{awk}. +* Funzione round:: Una funzione per eseguire + arrotondamenti se @code{sprintf()} + non lo fa correttamente. +* Funzione random Cliff:: Il generatore Cliff di numeri casuali. +* Funzioni ordinali:: Funzioni per usare caratteri come + numeri e viceversa. +* Funzione join:: Una funzione per raccogliere un + vettore in una stringa. +* Funzione getlocaltime:: Una funzione per ottenere data e + ora nel formato desiderato. +* Funzione readfile:: Una funzione per leggere un file + intero in un colpo solo. +* Apici alla shell:: Una funzione per passare stringhe + con apici alla shell. +* Gestione File Dati:: Funzioni for gestire file dati + specificati sulla riga di comando, +* Funzione filetrans:: Una funzione per gestire il passaggio + da un file in input al successivo. +* Funzione rewind:: Una funzione per rileggere il file + di input. +* Controllo di file:: Controllare che i file in input siano + accessibili. +* File vuoti:: Controllare se i file in input sono + vuoti. +* Ignorare assegnamenti di variabili:: Trattare assegnamenti di variabili + come nomi di file. +* Funzione getopt:: Una funzione per trattare argomenti + presenti sulla riga di comando. +* Funzioni Passwd:: Funzioni per ottenete informazioni + sull'utente [da /etc/passwd]. +* Funzioni Group:: Funzioni per ottenete informazioni + sul gruppo [da /etc/group]. +* Visitare vettori:: Una funzione per visitare vettori + di vettori. +* Sommario funzioni di libreria:: Sommario funzioni di libreria. +* Esercizi con le librerie:: Esercizi. +* Eseguire esempi:: Come eseguire i programmi di esempio. +* Cloni:: Cloni di programmi di utilit@`a comuni. +* Programma cut:: Il programma di utilit@`a @command{cut}. +* Programma egrep:: Il programma di utilit@`a @command{egrep}. +* Programma id:: Il programma di utilit@`a @command{id}. +* Programma split:: Il programma di utilit@`a @command{split}. +* Programma tee:: Il programma di utilit@`a @command{tee}. +* Programma uniq:: Il programma di utilit@`a @command{uniq}. +* Programma wc:: Il programma di utilit@`a @command{wc}. +* Programmi vari:: Alcuni interessanti programmi in + @command{awk} +* Programma dupword:: Trovare parole duplicate in un + documento. +* Programma alarm:: Un programma di sveglia. +* Programma translate:: Un programma simile al comando di + utilit@`a @command{tr}. +* Programma labels:: Stampare etichette per lettere. +* Programma utilizzo parole:: Un programma per produrre un contatore + dell'utilizzo di parole in un testo. +* Programma riordino diario:: Eliminare righe doppie da un file di + cronologia. +* Programma extract:: Estrarre programmi da file sorgenti + Texinfo. +* Programma sed semplice:: Un semplice editor di flusso. +* Programma igawk:: Un programma per fornire ad + @command{awk} la possibilit@`a di + includere file. +* Programma anagram:: Trovare anagrammi da una lista di + parole. +* Programma signature:: La gente fa cose stupefacenti se ha + troppo tempo libero. +* Sommario dei programmi:: Sommario dei programmi. +* Esercizi sui programmi:: Esercizi. +* Dati non decimali:: Consentire dati di input in base + diversa da 10. +* Ordinamento di vettori:: Modi per controllare la visita di un + vettore e il suo ordinamento. +* Controllare visita vettori:: Come usare PROCINFO["sorted_in"]. +* Funzioni di ordinamento di vettori:: Come usare @code{asort()} e + @code{asorti()}. +* I/O bidirezionale:: Comunicazione nei due sensi con un + altro processo. +* Reti TCP/IP:: Usare @command{gawk} per + programmazione di rete. +* Profilare:: Profilare i propri programmi + @command{awk}. +* Sommario funzionalit@`a avanzate:: Sommario funzionalit@`a avanzate. +* I18N e L10N:: Internazionalizzazione e localiz. +* Utilizzare @command{gettext}:: Come funziona GNU @code{gettext}. +* I18N per programmatore:: Funzionalit@`a per il programmatore. +* I18N per traduttore:: Funzionalit@`a per il traduttore. +* Estrazione di stringhe:: Estrarre stringhe marcate. +* Ordinamento di printf:: Riordinare argomenti @code{printf} + [nelle stringhe da tradurre]. +* Portabilit@`a nell'I18N:: Problemi di portabilit@`a a livello di + @command{awk}. +* Esempio I18N:: Un semplice esempio di + internazionalizzazione. +* Gawk internazionalizzato:: @command{gawk} stesso @`e + internazionalizzato. +* Sommario I18N:: Sommario sull'internazionalizzazione. +* Debugging:: Introduzione al debugger di + @command{gawk}. +* Nozioni sul debug:: Generalit@`a sul debug. +* Terminologia nel debug:: Concetti fondamentali sul debug. +* Debug di Awk:: Il debug di @command{awk}. +* Esempio di sessione di debug:: Esempio di sessione di debug di + @command{gawk}. +* Invocazione del debugger:: Come avviare il debugger. +* Trovare il bug:: Trovare il bug. +* Lista dei comandi di debug:: I principali comandi di debug. +* Controllo dei breakpoint:: Controllo dei punti d'interruzione. +* Controllo esecuzione debugger:: Controllo di esecuzione. +* Vedere e modificare dati:: Vedere e modificare dati. +* Stack di esecuzione:: Lavorare con lo stack. +* Informazioni sul debugger:: Ottenere informazioni sullo stato + del programma e del debugger. +* Comandi vari del debugger:: Comandi vari del debugger. +* Supporto per Readline:: Supporto per Readline. +* Limitazioni:: Limitazioni. +* Sommario sul debug:: Sommario sul debug. +* Aritmetica del computer:: Una rapida introduzione alla matematica del + computer. +* Definizioni matematiche:: Altre cose da sapere. +* Funzionalit@`a MPFR:: Funzionalit@`a per il calcolo a + precisione arbitraria in @command{gawk} +* Cautela col calcolo in VM:: Cose da sapere. +* Inesattezza nei calcoli:: La matematica in virgola mobile non @`e + esatta. +* Rappresentazioni inesatte:: Molti numeri non sono rappresentati + esattamente. +* Confronti tra valori in VM:: Come confrontare valori in virgola mobile. +* Gli errori si sommano:: Gli errori diventano sempre maggiori. +* Ottenere la precisione:: Ottenere la precisione voluta. +* Tentare di arrotondare:: Tentare di aggiungere bit di precisione e + arrotondare. +* Impostare la precisione:: Impostare la precisione. +* Impostare modi di arrotondare:: Impostare la modalit@`a di + arrotondamento. +* Interi a precisione arbitraria:: Aritmetica dei numeri interi a precisione + arbitraria con @command{gawk}. +* Problemi virgola mobile POSIX:: Confronto tra standard e uso corrente. +* Sommario virgola mobile:: Sommario della trattazione della + virgola mobile. +* Introduzione alle estensioni:: Cos'@`e un'estensione. +* Licenza delle estensioni:: tipo di licenza delle estensioni. +* Panoramica sul meccanismo delle estensioni:: Come funziona a grandi linee. +* Descrizione dell'API delle estensioni:: Una descrizione completa dell'API. +* Intro funzioni API delle estensioni:: Introduzione alle funzioni dell'API. +* Tipi di dati generali:: I tipi di dati. +* Funzioni di allocazione memoria:: Funzioni per allocare memoria. +* Funzioni di costruzione:: Funzioni per creare valori. +* Funzioni di registrazione:: Funzioni per registrare cose con + @command{gawk}. +* Funzioni di estensione:: Registrare funzioni di estensione. +* Funzioni di exit callback:: Registrare una exit di callback. +* Stringa di versione Estensioni:: Registrare una stringa di versione. +* Analizzatori di input:: Registrare un analizzatore di input. +* Processori di output:: Registrare un processore di output. +* Processori bidirezionali:: Registrare un processore + bidirezionale. +* Stampare messaggi:: Stampare messaggi dalle estensioni. +* Aggiornare @code{ERRNO}:: Funzioni per aggiornare @code{ERRNO}. +* Richiedere valori:: Come ottenere un valore. +* Accedere ai parametri:: Funzioni per acceder ai parametri. +* Accedere alla tabella simboli:: Funzioni per accedere alle variabili + globali. +* Tabella simboli per nome:: Accedere e aggiornare variabili per nome. +* Tabella simboli tramite cookie:: Accedere alle variabili per ``cookie''. +* Valori nascosti:: Creare e usare valori nascosti. +* Manipolazione di vettori:: Funzioni per lavorare coi vettori. +* Tipi di dati per i vettori:: Tipi dati per lavorare coi vettori. +* Funzioni per i vettori:: Funzioni per lavorare coi vettori. +* Appiattimento di vettori:: Come appiattire i vettori. +* Creazione di vettori:: Come creare e popolare vettori. +* Ridirezione API:: Come accedere alla ridirezioni e + modificarle. +* Variabili dell'estensione API:: Variabili fornite dall'API. +* Versione dell'estensione:: Informazioni sulla versione API. +* Variabili informative di estens. API:: Variabili che forniscono informazioni + sull'invocazione di @command{gawk}. +* Codice predefinito di un'estensione API:: Codice predefinito di interfaccia API. +* Modifiche dalla versione API 1:: Modifiche dalla versione 1 dell'API. +* Trovare le estensioni:: Come @command{gawk} trova le + estensioni compilate. +* Esempio di estensione:: Esempio di codice C di un'estensione. +* Descrizione interna file:: Quello che le nuove funzioni faranno. +* Operazioni interne file:: Codice per gestire file all'interno. +* Usare operazioni interne file:: Come usare un'estensione esterna. +* Esempi di estensione:: Le estensioni di esempio incluse con + @command{gawk}. +* Esempio di estensione funzioni file:: Funzioni relative ai file. +* Esempio di estensione Fnmatch:: Un'interfaccia a @code{fnmatch()}. +* Esempio di estensione Fork:: Un'interfaccia a @code{fork()} e + altre funzioni di processo. +* Esempio di estensione Inplace:: Consentire modifica file input + nell'estensione. +* Esempio di estensione Ord:: Conversioni di caratteri in valori + numerici e viceversa. +* Esempio di estensione Readdir:: Un'interfaccia a @code{readdir()}. +* Esempio di estensione Revout:: Invertire la stringa in output. +* Esempio di estensione Rev2way:: Esempio di I/O bidirezionale. +* Esempio di estensione Rwarray:: Scaricare e ricaricare un vettore. +* Esempio di estensione Readfile:: Leggere un intero file in una stringa. +* Esempio di estensione Time:: Un'interfaccia a @code{gettimeofday()} + e @code{sleep()}. +* Esempio di estensione API Test:: Test per la API. +* gawkextlib:: Il progetto @code{gawkextlib}. +* Sommario delle estensioni:: Sommario delle estensioni. +* Esercizi sulle estensioni:: Esercizi. +* V7/SVR3.1:: Le principali differenze tra V7 e + System V Release 3.1. +* SVR4:: Differenze minori tra System V + Release 3.1 e 4. +* POSIX:: Nuove funzionalit@`a per lo standard + POSIX. +* BTL:: Nuove funzionalit@`a dalla versione + di @command{awk} di Brian Kernighan. +* POSIX/GNU:: Le estensioni in @command{gawk} non + previste in @command{awk} POSIX. +* Storia delle funzionalit@`a:: Storia delle funzionalit@`a di + @command{gawk}. +* Estensioni comuni:: Sommario Estensioni comuni. +* Intervalli e localizzazione:: Come le localizzazioni influiscono + sugli intervalli delle espressioni + regolari. +* Contributori:: I maggiori contributori a + @command{gawk}. +* Sommario della storia:: Sommario della storia. +* Distribuzione di Gawk:: Contenuto della distribuzione di + @command{gawk}. +* Scaricare:: Come ottenere la distribuzione. +* Scompattazione:: Come estrarre la distribuzione. +* Contenuti della distribuzione:: Cosa c'@`e nella distribuzione. +* Installazione Unix:: Installare @command{gawk} su + varie versioni di Unix. +* Installazione veloce:: Compilare @command{gawk} sotto Unix. +* File da usare a inizio sessione:: Funzioni di personalizzazione shell. +* Ulteriori opzioni di configurazione:: Altre opzioni utilizzabili in fase + di compilazione. +* Filosofia della configurazione:: Come si suppone che funzioni. +* Installazione non-Unix:: Installazioni su altri Sistemi + Operativi. +* Installazione su PC:: Installare e compilare + @command{gawk} su Microsoft Windows. +* Installazione binaria su PC:: Installare una distribuzione pronta + all'uso. +* Compilazione su PC:: Compilare @command{gawk} per + Windows32. +* Uso su PC:: Eseguire @command{gawk} su Windows32. +* Cygwin:: Compilare ed eseguire @command{gawk} + per Cygwin. +* MSYS:: Usare @command{gawk} nell'ambiente + MSYS. +* Installazione su VMS:: Installare @command{gawk} su VMS. +* Compilazione su VMS:: Come compilare @command{gawk} su + VMS. +* Estensioni dinamiche su VMS:: Compilare estensioni dinamiche + di @command{gawk} su VMS. +* Dettagli installazione su VMS:: Come installare @command{gawk} su + VMS. +* Esecuzione su VMS:: Come eseguire @command{gawk} su VMS. +* GNV su VMS:: Il progetto GNV di VMS. +* Vecchio Gawk su VMS:: Una versione non aggiornata arriva + con alcune versioni di VMS. +* Bug:: Notificare problemi e bug. +* Indirizzo Bug:: Dove notificare problemi. +* Usenet:: Dove non notificare problemi. +* Manutentori:: Manutentori di version non-*nix. +* Altre versioni:: Altre implementazioni di + @command{awk} liberamente + disponibili. +* Sommario dell'installazione:: Sommario dell'installazione. +* Modalit@`a di compatibilit@`a:: Come inibire alcune estensioni di + @command{gawk}. +* Aggiunte:: Fare aggiunte a @command{gawk}. +* Accedere ai sorgenti:: Accedere al deposito sorgenti Git. +* Aggiungere codice:: Aggiungere codice al programma + principale @command{gawk}. +* Nuovi sistemi:: Rendere disponibile @command{gawk} + a un nuovo sistema operativo. +* File derivati:: Perch@'e i file ancillari sono tenuti + nel deposito @command{git}. +* Future estensioni:: Nuove funzionalit@`a che potranno + essere implementate in futuro. +* Limitazioni dell'implementazione:: Alcune limitazioni + dell'implementazione. +* Progetto delle estensioni:: Note di progetto sull'estensione API. +* Problemi con le vecchie estensioni:: Problemi con la precedente + implementazione di estensioni. +* Obiettivi delle estensioni:: Obiettivi del nuovo meccanismo. +* Altre scelte progettuali per le estensioni:: Qualche altra scelta progettuale. +* Futuri sviluppi delle estensioni:: Possibilit@`a di crescita futura. +* Meccanismo delle vecchie estensioni:: Problemi con le vecchie estensioni. +* Sommario delle note:: Sommario delle note di + implementazione. +* Fondamenti ad alto livello:: Una visione dall'alto. +* Fondamenti sui tipi di dati:: Una velocissima introduzione ai tipi + di dati. +@end detailmenu +@end menu + +@c dedication for Info file +@ifinfo +Ai miei genitori, per il loro amore, e per lo splendido +esempio che mi hanno dato. +@sp 1 +A mia moglie Miriam, per avermi reso completo. +Grazie per aver costruito la tua vita insieme a me. +@sp 1 +Ai nostri figli Chana, Rivka, Nachum e Malka, +per aver arricchito le nostre vite in misura incalcolabile. +@end ifinfo + +@ifset SMALLPRINT +@fonttextsize 10 +@end ifset + +@summarycontents +@contents + +@ifset SMALLPRINT +@fonttextsize 11 +@end ifset + +@node Introduzione3 +@unnumbered Introduzione alla Terza Edizione + +@c This bit is post-processed by a script which turns the chapter +@c tag into a preface tag, and moves this stuff to before the title. +@c Bleah. +@docbook + <prefaceinfo> + <author> + <firstname>Michael</firstname> + <surname>Brennan</surname> + <!-- can't put mawk into command tags. sigh. --> + <affiliation><jobtitle>Autore di mawk</jobtitle></affiliation> + </author> + <date>Marzo 2001</date> + </prefaceinfo> +@end docbook + +Arnold Robbins e io siamo buoni amici. Ci siamo conosciuti +@c 11 years ago +nel 1990 per un insieme di +circostanze---e per il nostro linguaggio di programmazione preferito, AWK. +Tutto era iniziato un paio d'anni prima. +Avevo appena iniziato un nuovo lavoro e avevo notato un computer Unix scollegato +che giaceva in un angolo. +Nessuno sapeva come usarlo, tanto meno io. Comunque, +qualche giorno pi@`u tardi, stava funzionando, con +me come @code{root} e solo e unico utente. +Quel giorno, iniziai la transizione da statistico a programmatore Unix. + +In uno dei miei giri per biblioteche e librerie alla ricerca di libri sullo +Unix, trovai il libro, dalla copertina grigia, su AWK, noto anche come @: +Alfred V.@: Aho, Brian W.@: Kernighan e +Peter J.@: Weinberger, @cite{The AWK Programming Language}, (Addison-Wesley, +1988). Il semplice paradigma di programmazione di AWK +---trovare un'espressione di ricerca nell'input e di conseguenza compiere +un'azione---riduceva spesso +complesse e tediose manipolazioni di dati a poche righe di codice. Ero +entusiasta di cimentarmi nella programmazione in AWK. + +Ahim@`e, l'@command{awk} sul mio computer era una versione limitata del +linguaggio descritto nel libro grigio. Scoprii che il mio computer aveva il +``vecchio @command{awk}'' mentre il libro descriveva il ``nuovo +@command{awk}.'' +Imparai che non era un caso isolato; la vecchia versione si rifiutava di farsi da +parte o di cedere il suo nome. Se un sistema aveva un nuovo @command{awk}, +questo era chiamato invariabilmente @command{nawk}, e pochi sistemi lo avevano. +Il miglior modo per ottenere un nuovo @command{awk} era quello di scaricare via +@command{ftp} il codice sorgente di @command{gawk} da @code{prep.ai.mit.edu}. +@command{gawk} era una versione del nuovo @command{awk} scritta da David Trueman +e Arnold, e disponibile sotto la GNU General Public License. + +Per inciso, ora non @`e +pi@`u cos@`{@dotless{i}} difficile trovare un nuovo @command{awk}. @command{gawk} viene +fornito con GNU/Linux, e si possono scaricare i binari e il codice sorgente per +quasi tutti i sistemi; mia moglie usa @command{gawk} nella sua stazione di lavoro VMS. + +Il mio sistema Unix non era inizialmente collegato a una presa di corrente; a +maggior ragione non era collegato a una rete. Cos@`{@dotless{i}}, ignaro dell'esistenza di +@command{gawk} e in generale della comunit@`a di Unix, e desiderando un nuovo +@command{awk}, ne scrissi uno mio, chiamato @command{mawk}. Prima di aver +finito, scoprii l'esistenza di @command{gawk}, +ma era troppo tardi per fermarmi, cos@`{@dotless{i}} alla fine inviai un messaggio +a un newsgroup @code{comp.sources}. + +Qualche giorno dopo ricevetti un cordiale messaggio di posta elettronica +da Arnold che si presentava. +Propose di scambiarci progetti e algoritmi, e +alleg@`o una bozza dello standard POSIX, che mi permise di +aggiornare @command{mawk} per includere le estensioni al linguaggio +aggiunte dopo la pubblicazione di @cite{The AWK Programming Language}. + +Francamente, se i nostri ruoli fossero stati +invertiti, io non sarei stato cos@`{@dotless{i}} disponibile e probabilmente non ci +saremmo mai incontrati. Sono felice che l'incontro sia avvenuto. +Lui @`e un vero esperto tra gli esperti di AWK e una persona squisita. +Arnold mette a disposizione della Free Software Foundation parti significative +della sua esperienza e del suo tempo. + +Questo libro @`e il manuale di riferimento di @command{gawk}, ma sostanzialmente +@`e un libro sulla programmazione in AWK che +interesser@`a un vasto pubblico. +@`E un riferimento completo al linguaggio AWK come definito dalla versione del +1987 di Bell Laboratories e codificato nelle POSIX Utilities +standard del 1992. + +D'altra parte, un programmatore AWK alle prime armi pu@`o studiare +una quantit@`a di programmi pratici che permettono di apprezzare +la potenza dei concetti di base di AWK: +flusso di controllo guidato dai dati, ricerca di corrispondenze tramite +espressioni regolari e vettori associativi. +Chi desidera qualcosa di nuovo pu@`o provare l'interfaccia di @command{gawk} +verso i protocolli di rete attraverso i file speciali @file{/inet}. + +I programmi in questo libro evidenziano come un programma AWK sia +generalmente molto pi@`u piccolo e veloce da sviluppare +di uno equivalente scritto in C. +Di conseguenza, @`e spesso conveniente creare un prototipo di un +algoritmo o di un progetto in AWK per arrivare a eseguirlo in breve tempo e +scoprire prima i problemi che possono presentarsi. Spesso, l'efficienza di +questa versione iniziale interpretata @`e sufficiente e il prototipo +AWK diventa il prodotto finale. + +Il nuovo comando @command{pgawk} (profiling @command{gawk}) produce +conteggi sull'esecuzione delle istruzioni del programma. +Recentemente ho fatto un tentativo con un algoritmo che, a fronte di +@ifnotdocbook +@math{n} +@end ifnotdocbook +@ifdocbook +@i{n} +@end ifdocbook +righe di input, produceva il risultato in un tempo +@tex +$\sim\! Cn^2$, +@end tex +@ifnottex +@ifnotdocbook +~ C n^2, +@end ifnotdocbook +@end ifnottex +@docbook +<emphasis>∼ Cn<superscript>2</superscript></emphasis> +@end docbook +mentre in teoria +avrebbe dovuto terminare in un tempo +@tex +$\sim\! Cn\log n$. +@end tex +@ifnottex +@ifnotdocbook +~ C n log n. +@end ifnotdocbook +@end ifnottex +@docbook +<emphasis>∼ Cn log n</emphasis> +@end docbook +Dopo qualche minuto di attenta lettura +del profilo in @file{awkprof.out}, ho ricondotto il problema a +una singola riga di codice. @command{pgawk} @`e una gradita integrazione +ai miei strumenti di programmatore. + +Arnold ha condensato in questo libro oltre un decennio di esperienza nell'uso di +programmi AWK e nello sviluppo di @command{gawk}. Se si vuole usare +AWK o imparare ad usarlo, @`e consigliabile leggere questo libro. + +@ifnotdocbook +@cindex Brennan, Michael +@display +Michael Brennan +Autore di @command{mawk} +Marzo 2001 +@end display +@end ifnotdocbook + +@node Introduzione4 +@unnumbered Introduzione alla Quarta Edizione + +@c This bit is post-processed by a script which turns the chapter +@c tag into a preface tag, and moves this stuff to before the title. +@c Bleah. +@docbook + <prefaceinfo> + <author> + <firstname>Michael</firstname> + <surname>Brennan</surname> + <!-- can't put mawk into command tags. sigh. --> + <affiliation><jobtitle>Autore di mawk</jobtitle></affiliation> + </author> + <date>Ottobre 2014</date> + </prefaceinfo> +@end docbook + +Ci sono cose che non cambiano. Tredici anni fa scrivevo: +``Se si vuole usare AWK o imparare ad usarlo, @`e consigliabile +leggere questo libro.'' +Era vero allora e rimane vero anche oggi. + +Imparare a usare un linguaggio di programmazione richiede qualcosa di pi@`u +che padroneggiarne la sintassi. Occorre comprendere come +usare le funzionalit@`a del linguaggio per risolvere problemi pratici di +programmazione. Uno dei punti pi@`u importanti di questo libro @`e che +fornisce molti esempi che mostrano come utilizzare AWK. + +Altre cose, invece, cambiano. I nostri computer sono diventati molto pi@`u +veloci e la loro memoria @`e molto pi@`u estesa. +Per questa ragione, la velocit@`a di esecuzione e l'uso efficiente della +memoria, caratteristiche di un linguaggio di livello elevato, hanno minore +rilevanza. +Scrivere un programma prototipo in AWK per poi riscriverlo in C per +migliorare l'utilizzo delle risorse capita sempre meno, perch@'e sempre pi@`u +spesso il prototipo @`e abbastanza veloce anche per essere messo in produzione. + +Naturalmente, ci sono tipi di calcoli che sono effettuati pi@`u agevolmente +da programmi scritti in C o C++. +Con @command{gawk} 4.1 e successive versioni, non @`e necessario +decidere se scrivere un programma in AWK oppure in C/C++. Si pu@`o scrivere +buona parte del programma in AWK e le parti che richiedono +specificamente il C/C++ possono essere scritte in C/C++ e quindi il tutto +pu@`o essere eseguito come un programma unico, con il modulo @command{gawk} +che carica dinamicamente il modulo C/C++ in fase di esecuzione. +@c Chapter 16 +@iftex +Il +@end iftex +@ref{Estensioni dinamiche}, +spiega la procedura in gran +dettaglio, e, come prevedibile, riporta molti esempi che sono di aiuto per +approfondire anche gli aspetti pi@`u complessi. + +@`E per me un piacere programmare in AWK ed @`e stato divertente (ri)leggere +questo libro. Penso che sar@`a lo stesso per voi. + +@ifnotdocbook +@cindex Brennan, Michael +@display +Michael Brennan +Autore di @command{mawk} +Ottobre 2014 +@end display +@end ifnotdocbook +@node Prefazione +@unnumbered Prefazione +@c I saw a comment somewhere that the preface should describe the book itself, +@c and the introduction should describe what the book covers. +@c +@c 12/2000: Chuck wants the preface & intro combined. + +@c This bit is post-processed by a script which turns the chapter +@c tag into a preface tag, and moves this stuff to before the title. +@c Bleah. +@docbook + <prefaceinfo> + <author> + <firstname>Arnold</firstname> + <surname>Robbins</surname> + <affiliation><jobtitle>Nof Ayalon</jobtitle></affiliation> + <affiliation><jobtitle>Israel</jobtitle></affiliation> + </author> + <date>Febbraio 2015</date> + </prefaceinfo> +@end docbook + +Lavorando con file di testo capita di dover eseguire alcuni tipi ripetitivi di +operazioni. Si potrebbe voler estrarre alcune righe e scartare il resto, o fare +modifiche laddove siano verificate certe condizioni, lasciando inalterato il +resto del file. Questi compiti risultano spesso pi@`u agevoli usando +@command{awk}. Il programma di utilit@`a @command{awk} interpreta un linguaggio +di programmazione specializzato che rende facile eseguire semplici attivit@`a +di riformattazione di dati. + +@cindex Brian Kernighan, @command{awk} di +L'implementazione GNU di @command{awk} @`e chiamata @command{gawk}; se +invocato con le opzioni o con le variabili d'ambiente appropriate, +(@pxref{Opzioni}), @`e pienamente +compatibile con le specifiche +POSIX@footnote{Lo standard POSIX 2008 @`e accessibile in rete all'indirizzo +@w{@url{http://www.opengroup.org/onlinepubs/9699919799/}.}} +del linguaggio @command{awk} +e con la versione Unix di @command{awk} mantenuta +da Brian Kernighan. +Ci@`o implica che tutti i programmi +@command{awk} scritti correttamente dovrebbero funzionare con @command{gawk}. +Perci@`o nella maggior parte dei casi non si distingue tra @command{gawk} e +altre implementazioni di @command{awk}. + +@cindex @command{awk}, POSIX e, si veda anche POSIX @command{awk} +@cindex @command{awk}, POSIX e +@cindex POSIX, @command{awk} e +@cindex @command{gawk}, @command{awk} e +@cindex @command{awk}, @command{gawk} e +@cindex @command{awk}, uso di +Usando @command{awk} potete: + +@itemize @value{BULLET} +@item +Gestire piccole basi di dati personali + +@item +Generare rapporti + +@item +Validare dati + +@item +Produrre indici ed effettuare altre operazioni per la preparazione di documenti + +@item +Sperimentare algoritmi che possono essere adattati in seguito ad altri +linguaggi per computer +@end itemize + +@cindex @command{awk}, si veda anche @command{gawk} +@cindex @command{gawk}, si veda anche @command{awk} +@cindex @command{gawk}, uso di +Inoltre, +@command{gawk} +fornisce strumenti che rendono facile: + +@itemize @value{BULLET} +@item +Estrarre frammenti di dati per l'elaborazione + +@item +Ordinare dati + +@item +Effettuare semplici comunicazioni di rete + +@item +Creare il profilo di esecuzione ed effettuare il debug +di programmi @command{awk}. + +@item +Estendere il linguaggio con funzioni scritte in C o C++. +@end itemize + +Questo @value{DOCUMENT} spiega il linguaggio @command{awk} e come lo si pu@`o +usare efficacemente. @`E richiesta una familiarit@`a coi comandi di sistema +di base, come @command{cat} e @command{ls},@footnote{Questi programmi di +utilit@`a sono disponibili sui sistemi conformi a POSIX, come pure sui sistemi +tradizionali basati su Unix. Se si usa qualche altro sistema operativo, si +deve comunque avere familiarit@`a con i concetti di ridirezione I/O e di +@dfn{pipe}.} cos@`{@dotless{i}} come con le funzionalit@`a di base della shell, come la +ridirezione, l'input/output (I/O) e le @dfn{pipe}. + +@cindex GNU @command{awk}, si veda @command{gawk} +Implementazioni del linguaggio @command{awk} sono disponibili per diversi +sistemi operativi di computer. Questo @value{DOCUMENT}, oltre a descrivere il +linguaggio @command{awk} in generale, descrive anche la specifica +implementazione di @command{awk} chiamata @command{gawk} (che sta per +``GNU @command{awk}''). @command{gawk} funziona su una vasta gamma di sistemi +Unix, dai PC basati su architettura Intel fino +a sistemi di potenza molto maggiore. +@command{gawk} @`e stato portato anche su Mac OS X, +Microsoft Windows +(tutte le versioni), +e OpenVMS.@footnote{Qualche altro sistema operativo obsoleto su cui +@command{gawk} era stato portato non @`e pi@`u mantenuto e il codice specifico +per quei sistemi @`e stato rimosso.} + +@menu +* Storia:: La storia di @command{gawk} e + @command{awk}. +* Nomi:: Che nome usare per trovare + @command{awk}. +* Questo manuale:: Uso di questo @value{DOCUMENT}. + Comprende esempi di file in input + utilizzabili. +* Convenzioni:: Convenzioni tipografiche. +* Storia del manuale:: Breve storia del Progetto GNU e di + questo @value{DOCUMENT}. +@ifset FOR_PRINT +* Aggiornamenti:: Come tenersi al corrente. +@end ifset +* Come contribuire:: Un aiuto per la salvezza del mondo. +* Ringraziamenti:: Ringraziamenti. +@end menu + +@node Storia +@unnumberedsec La storia di @command{gawk} e @command{awk} +@cindex ricetta per un linguaggio di programmazione +@cindex linguaggio di programmazione, ricetta per un +@cindex programmazione, ricetta per un linguaggio di +@sidebar Ricetta per un linguaggio di programmazione + +@multitable {2 parti di} {1 parte di @code{egrep}} {1 parte di @code{snobol}} +@item @tab 1 parte di @code{egrep} @tab 1 parte di @code{snobol} +@item @tab 2 parti di @code{ed} @tab 3 parti di C +@end multitable + +Mescolare bene tutte le parti usando @code{lex} e @code{yacc}. +Preparare una concisa documentazione e distribuire. + +Dopo otto anni, aggiungere un'altra parte di @code{egrep} e altre due +parti di C. Documentare molto bene e distribuire. +@end sidebar + +@cindex Aho, Alfred +@cindex Weinberger, Peter +@cindex Kernighan, Brian +@cindex @command{awk}, storia di +Il nome @command{awk} deriva dalle iniziali dei suoi progettisti: Alfred V.@: +Aho, Peter J.@: Weinberger e Brian W.@: Kernighan. La versione originale di +@command{awk} fu scritta nel 1977 negli AT&T Bell Laboratories. +Nel 1985, una nuova versione rese il linguaggio di programmazione +pi@`u potente, introducendo le funzioni definite dall'utente, flussi di input +multipli ed espressioni regolari calcolate. +Questa nuova versione ebbe larga diffusione con Unix System V +Release 3.1 (1987). +La versione in System V Release 4 (1989) ha aggiunto alcune nuove funzionalit@`a +e ha fatto pulizia nel comportamento di alcuni degli ``punti oscuri'' del +linguaggio. Le specifiche per @command{awk} nello standard POSIX Command +Language and Utilities ha in seguito reso pi@`u chiaro il linguaggio. Sia i +progettisti di @command{gawk} che quelli dell'originale @command{awk} dei Bell +Laboratories hanno collaborato alla formulazione delle specifiche POSIX. + +@cindex Rubin, Paul +@cindex Fenlason, Jay +@cindex Trueman, David +Paul Rubin ha scritto @command{gawk}, nel 1986. +Jay Fenlason l'ha completata, seguendo i consigli di Richard Stallman. +Anche John Woods ha fornito parti del codice. Nel 1988 e 1989, David Trueman, +col mio aiuto, ha rivisto completamente @command{gawk} per la compatibilit@`a +col pi@`u recente @command{awk}. +Intorno al 1994, sono divenuto il manutentore principale. +Lo sviluppo corrente @`e incentrato sulla correzione degli errori, sul +miglioramento delle prestazioni, sulla conformit@`a agli standard e, +occasionalmente, su nuove funzionalit@`a. + +Nel maggio 1997, J@"urgen Kahrs avvert@`{@dotless{i}} la necessit@`a di un accesso alla +rete da @command{awk}, e con un piccolo aiuto da parte mia, cominci@`o ad +aggiungere funzionalit@`a a @command{gawk} per fare questo. A quel tempo, +lui scrisse anche il grosso di +@cite{@value{GAWKINETTITLE}} +(un documento separato, disponibile come parte della distribuzione +@command{gawk}). Il suo codice alla fine venne integrato nella distribuzione +principale di @command{gawk} con la versione 3.1 di @command{gawk}. + +John Haque ha riscritto la parte interna di @command{gawk}, mentre metteva a +punto un debugger a livello di @command{awk}. Questa versione divenne +disponibile come @command{gawk} versione 4.0 nel 2011. + +@xref{Contributori} +per un elenco completo di quelli che hanno fornito contributi importanti a +@command{gawk}. + +@node Nomi +@unnumberedsec Una rosa, con ogni altro nome... + +@cindex @command{awk}, nuovo e vecchio +Il linguaggio @command{awk} si @`e evoluto nel corso degli anni. Tutti i +dettagli si trovano in @ref{Storia del linguaggio}. +Il linguaggio descritto in questo @value{DOCUMENT} +viene spesso citato come ``nuovo @command{awk}''. +Per analogia, la versione originale di @command{awk} @`e citata +come ``vecchio @command{awk}.'' + +Su molti sistemi di uso corrente, eseguendo il programma di utilit@`a +@command{awk}, si invoca qualche versione del nuovo +@command{awk}.@footnote{Solo i sistemi Solaris usano ancora un +vecchio @command{awk} per il programma di utilit@`a predefinito +@command{awk}. Una versione pi@`u moderna di @command{awk} si trova +nella directory @file{/usr/xpg6/bin} su questi sistemi.} Se +il comando @command{awk} nel sistema in uso @`e il vecchio, il +risultato che vedrete per il programma di test che segue @`e +del tipo: + +@example +$ @kbd{awk 1 /dev/null} +@error{} awk: syntax error near line 1 +@error{} awk: bailing out near line 1 +@end example + +@noindent +Se questo @`e il caso, dovreste cercare una versione del nuovo @command{awk}, +o semplicemente installare @command{gawk}! + +All'interno di questo @value{DOCUMENT}, quando si fa riferimento a +funzionalit@`a del linguaggio che dovrebbe essere disponibile in ogni +implementazione completa di @command{awk} POSIX, viene usato il termine +@command{awk}. Quando si fa riferimento a una funzionalit@`a specifica +dell'implementazione GNU, viene usato i termine @command{gawk}. + +@node Questo manuale +@unnumberedsec Uso di questo @value{DOCUMENT} +@cindex @command{awk}, descrizione dei termini + +Il termine @command{awk} si riferisce sia a uno specifico programma sia al +linguaggio che si usa per dire al programma stesso cosa deve fare. Quando dobbiamo +essere precisi, chiamiamo il linguaggio ``il linguaggio @command{awk},'' +e il programma ``l'utilit@`a @command{awk}.'' +Questo @value{DOCUMENT} spiega +sia come scrivere programmi nel linguaggio @command{awk} che come +eseguire l'utilit@`a @command{awk}. +Il termine ``programma @command{awk}'' si riferisce a un programma scritto +dall'utente nel linguaggio di programmazione @command{awk}. + +@cindex @command{gawk}, @command{awk} e +@cindex @command{awk}, @command{gawk} e +@cindex POSIX @command{awk} +In primo luogo, questo @value{DOCUMENT} spiega le funzionalit@`a di @command{awk} +come definite nello standard POSIX, e lo fa nel contesto dell'implementazione +@command{gawk}. Oltre a questo, cerca anche di descrivere le differenze +significative tra @command{gawk} +e altre +@ifclear FOR_PRINT +implementazioni @command{awk}.@footnote{Tutte queste differenze +si trovano nell'indice alla +voce ``differenze tra @command{awk} e @command{gawk}.''} +@end ifclear +@ifset FOR_PRINT +implementazioni @command{awk}. +@end ifset +Infine, vien fatta rilevare ogni funzionalit@`a di @command{gawk} non +inclusa nello standard POSIX per @command{awk}. + +@ifnotinfo +Questo @value{DOCUMENT} ha il difficile compito di essere tanto una guida +introduttiva che un manuale di riferimento. I neofiti possono +tranquillamente saltare i dettagli che sembrano loro troppo complessi. +Possono anche ignorare i molti riferimenti incrociati, preparati avendo in +mente gli utenti esperti e per le versioni Info e +@uref{http://www.gnu.org/software/gawk/manual/, HTML} +del @value{DOCUMENT}. +@end ifnotinfo + +Ci sono dei riquadri +sparsi in tutto il @value{DOCUMENT}. +Aggiungono una spiegazione pi@`u completa su punti importanti, ma che +probabilmente non sono di interesse in sede di prima lettura. +@ifclear FOR_PRINT +Si trovano tutti nell'indice analitico, alla voce ``sidebar.'' @c non c'e riquadro nell'indice analitico +@end ifclear + +La maggior parte delle volte, gli esempi usano programmi @command{awk} completi. +Alcune delle @value{SECTIONS} pi@`u avanzate mostrano solo la parte del programma +@command{awk} che illustra il concetto che si sta descrivendo. + +Sebbene questo @value{DOCUMENT} sia destinato soprattutto alle persone che non +hanno una precedente conoscenza di @command{awk}, esso contiene anche tante +informazioni che anche gli esperti di @command{awk} troveranno utili. +In particolare, dovrebbero essere d'interesse la descrizione di POSIX +@command{awk} e i programmi di esempio +@ifnottex +in +@end ifnottex +@iftex +nel +@end iftex +@ref{Funzioni di libreria} e +@ifnotdocbook +@ifnottex +in +@end ifnottex +@end ifnotdocbook +@iftex +nel +@end iftex +@ref{Programmi di esempio}. + +Questo @value{DOCUMENT} @`e suddiviso in diverse parti, come segue: + +@c FULLXREF ON + +@itemize @value{BULLET} +@item +La Parte I descrive il linguaggio @command{awk} e il programma @command{gawk} +nel dettaglio. +Inizia con le nozioni di base, e continua con tutte le caratteristiche di +@command{awk}. Contiene i seguenti capitoli: + +@c nested +@itemize @value{MINUS} +@item +@ref{Per iniziare}, +fornisce le nozioni minime indispensabili per iniziare a usare @command{awk}. + +@item +@ref{Invocare Gawk}, +descrive come eseguire @command{gawk}, il significato delle sue +opzioni da riga di comando e come trovare i file sorgenti del programma +@command{awk}. + +@item +@ref{Espressioni regolari}, +introduce le espressioni regolari in generale, e in particolare le variet@`a +disponibili in @command{awk} POSIX e @command{gawk}. + +@item +@ref{Leggere file}, +descrive come @command{awk} legge i dati inseriti dall'utente. +Introduce i concetti di record e campi, e anche il +comando @code{getline}. +Contiene una prima descrizione della ridirezione I/O, e una breve descrizione +dell'I/O di rete. + +@item +@ref{Stampare}, +descrive come i programmi @command{awk} possono produrre output con +@code{print} e @code{printf}. + +@item +@ref{Espressioni}, +descrive le espressioni, che sono i componenti elementari di base +per portare a termine la maggior parte delle operazioni in un programma. + +@item +@ref{Criteri di ricerca e azioni}, +descrive come scrivere espressioni di ricerca per individuare corrispondenze nei +record, le azioni da eseguire quando si @`e trovata una corrispondenza +in un record, e le variabili predefinite di @command{awk} e +@command{gawk}. + +@item +@ref{Vettori}, +tratta dell'unica struttura di dati di @command{awk}: il vettore associativo. +Vengono trattati anche l'eliminazione di elementi del vettore e di interi +vettori, e l'ordinamento dei vettori in @command{gawk}. +Il @value{CHAPTER} descrive inoltre come @command{gawk} fornisce vettori di +vettori. + +@item +@ref{Funzioni}, +descrive le funzioni predefinite fornite da @command{awk} e +@command{gawk}, e spiega come definire funzioni personalizzate. Viene +anche spiegato come @command{gawk} permetta di invocare funzioni in +maniera indiretta. +@end itemize + +@item +La Parte II illustra come usare @command{awk} e @command{gawk} per la +risoluzione di problemi. Qui ci sono molti programmi da leggere e da cui imparare. +Questa parte contiene i seguenti capitoli: + +@c nested +@itemize @value{MINUS} +@item +@ref{Funzioni di libreria}, +fornisce diverse funzioni pensate per +essere usate dai programmi scritti in @command{awk}. + +@item +@ref{Programmi di esempio}, +fornisce molti programmi @command{awk} di esempio. +@end itemize + +La lettura di questi due capitoli permette di capire come +@command{awk} pu@`o risolvere problemi pratici. + +@item +La Parte III si concentra sulle funzionalit@`a specifiche di @command{gawk}. +Contiene i seguenti capitoli: + +@c nested +@itemize @value{MINUS} +@item +@ref{Funzionalit@`a avanzate}, +descrive diverse funzionalit@`a avanzate. +Di particolare rilevanza sono +la capacit@`a di controllare l'ordine di visita dei vettori, +quella di instaurare comunicazioni bidirezionali con altri processi, +di effettuare connessioni di rete TCP/IP, e di +profilare i propri programmi @command{awk}. + +@item +@ref{Internazionalizzazione}, +descrive funzionalit@`a speciali per tradurre i messaggi +di programma in diverse lingue in fase di esecuzione. + +@item +@ref{Debugger}, descrive il debugger di @command{gawk}. + +@item +@ref{Calcolo con precisione arbitraria}, +illustra le capacit@`a di calcolo avanzate. + +@item +@ref{Estensioni dinamiche}, +descrive come aggiungere nuove variabili e +funzioni a @command{gawk} scrivendo estensioni in C o C++. +@end itemize + +@item +@ifclear FOR_PRINT +La Parte IV contiene le appendici, il Glossario, e due licenze relative, +rispettivamente, al codice sorgente di @command{gawk} e a questo +@value{DOCUMENT}. Contiene le seguenti appendici: +@end ifclear + +@ifset FOR_PRINT +La Parte IV contiene le seguenti appendici, +che includono la Licenza per Documentazione Libera GNU: +@end ifset + +@itemize @value{MINUS} +@item +@ref{Storia del linguaggio}, +descrive l'evoluzione del linguaggio @command{awk} dalla sua prima versione +fino a oggi. Descrive anche come @command{gawk} +ha acquisito nuove funzionalit@`a col passare del tempo. + +@item +@ref{Installazione}, +descrive come ottenere @command{gawk}, come compilarlo +sui sistemi compatibili con POSIX, +e come compilarlo e usarlo su diversi sistemi +non conformi allo standard POSIX. Spiega anche come segnalare gli errori +di @command{gawk} e dove si possono ottenere altre implementazioni +di @command{awk} liberamente disponibili. + +@ifset FOR_PRINT +@item +@ref{Copia}, +presenta la licenza applicabile al codice sorgente @command{gawk}. +@end ifset + +@ifclear FOR_PRINT +@item +@ref{Note}, +descrive come disabilitare le estensioni @command{gawk}, +come contribuire scrivendo del nuovo codice per @command{gawk}, +e alcune possibili direzioni per il futuro sviluppo di @command{gawk}. + +@item +@ref{Concetti fondamentali}, +fornisce del materiale di riferimento a livello elementare per chi +sia completamente digiuno di programmazione informatica. + +Il @ref{Glossario}, definisce quasi tutti i termini significativi +usati all'interno di questo @value{DOCUMENT}. Se si incontrano termini +coi quali non si ha familiarit@`a, questo @`e il posto dove cercarli. + +@item +@ref{Copia}, e +@ref{Licenza per Documentazione Libera GNU (FDL)}, +presentano le licenze che si applicano, rispettivamente, al codice sorgente +di @command{gawk} e a questo @value{DOCUMENT}. +@end ifclear +@end itemize +@end itemize + +@ifset FOR_PRINT +La versione di questo @value{DOCUMENT} distribuita con @command{gawk} +contiene ulteriori appendici e altro materiale. +Per ragioni di spazio, per questa edizione a stampa abbiamo tralasciato alcune +delle appendici. Si possono trovare in rete ai seguenti indirizzi: + +@itemize @value{BULLET} +@item +@uref{http://www.gnu.org/software/gawk/manual/html_node/Notes.html, +L'appendice sulle note di implementazione} +descrive come disabilitare le estensioni @command{gawk}, come contribuire +scrivendo del nuovo codice per @command{gawk}, dove reperire informazioni +su alcune possibili future direzioni dello sviluppo di @command{gawk}, e +sulle decisioni di progetto che hanno influito sulle estensioni API. + +@item +@uref{http://www.gnu.org/software/gawk/manual/html_node/Basic-Concepts.html, +L'appendice sui concetti fondamentali} +fornisce del materiale di riferimento a livello elementare per chi sia completamente a +digiuno di programmazione informatica. + +@item +@uref{http://www.gnu.org/software/gawk/manual/html_node/Glossary.html, +Il Glossario} +definisce la maggior parte, se non tutti, i termini significativi usati +nel corso del libro. Se si incontrano termini con cui non si ha familiarit@`a, +questo @`e il posto dove cercarli. + +@item +@uref{http://www.gnu.org/software/gawk/manual/html_node/GNU-Free-Documentation-License.html, la licenza GNU FDL} +@`e la licenza che vale per questo @value{DOCUMENT}. +@end itemize + +@c ok not to use CHAPTER / SECTION here +Alcuni dei capitoli hanno sezioni con esercizi; queste sono anche +state omesse dall'edizione a stampa ma sono disponibili online. +@end ifset + +@c FULLXREF OFF + +@node Convenzioni +@unnumberedsec Convenzioni tipografiche + +@cindex Texinfo +Questo @value{DOCUMENT} @`e scritto in @uref{http://www.gnu.org/software/texinfo/, Texinfo}, +il linguaggio di formattazione della documentazione GNU. Viene usato un unico +file sorgente Texinfo per produrre sia la versione a stampa della documentazione +sia quella online. +@ifnotinfo +A causa di ci@`o, le convenzioni tipografiche +sono leggermente diverse da quelle presenti in altri libri che potete aver letto. +@end ifnotinfo +@ifinfo +Questo @value{SECTION} documenta brevemente le convenzioni tipografiche usate in Texinfo. +@end ifinfo + +Gli esempi da immettere sulla riga di comando sono preceduti dai +comuni prompt di shell primario e secondario, @samp{$} e @samp{>}. +L'input che si inserisce viene mostrato @kbd{in questo modo}. +@c 8/2014: @print{} is stripped from the texi to make docbook. +@ifclear FOR_PRINT +L'output del comando @`e preceduto dal glifo ``@print{}'', che +in genere rappresenta lo standard output del comando. +@end ifclear +@ifset FOR_PRINT +L'output del comando, normalmente il suo standard output, @`e stampato +@code{in questo modo}. +@end ifset +Messaggi di errore e altri output sullo standard error del comando sono +preceduti dal glifo ``@error{}''. Per esempio: + +@example +$ @kbd{echo ciao su stdout} +@print{} ciao su stdout +$ @kbd{echo salve su stderr 1>&2} +@error{} salve su stderr +@end example + +@ifnotinfo +Nel testo, quasi tutto ci@`o che riguarda la programmazione, +per esempio i nomi dei comandi, +appare in @code{questo font}. I frammenti +di codice appaiono nello stesso font e tra apici, @samp{in questo modo}. +Ci@`o che viene sostituito dall'utente o dal programmatore +appare in @var{questo font}. +Le opzioni sono stampate cos@`{@dotless{i}}: @option{-f}. +I @value{FNS} sono indicati in questo modo: @file{/percorso/al/file}. +@ifclear FOR_PRINT +Certe cose sono +evidenziate @emph{in questo modo}, e se un punto dev'essere reso in modo pi@`u +marcato, viene evidenziato @strong{in questo modo}. +@end ifclear +La prima occorrenza di un +nuovo termine @`e usualmente la sua @dfn{definizione} e appare nello stesso +font della precedente occorrenza di ``definizione'' in questa frase. +@end ifnotinfo + +I caratteri che si battono sulla tastiera sono scritti come @kbd{questi}. In +particolare, ci sono caratteri speciali chiamati ``caratteri di controllo''. +Questi sono caratteri che vengono battuti tenendo premuti il tasto +@kbd{CONTROL} e un altro tasto contemporaneamente. +Per esempio, @kbd{Ctrl-d} @`e battuto premendo e tenendo premuto il tasto +@kbd{CONTROL}, poi premendo il tasto @kbd{d} e infine rilasciando entrambi i +tasti. + +Per amor di brevit@`a, in questo @value{DOCUMENT}, la versione di Brian +Kernighan di @command{awk} sar@`a citata come ``BWK @command{awk}.'' +(@xref{Altre versioni} per informazioni su questa e altre versioni.) + +@ifset FOR_PRINT +@quotation NOTA +Note interessanti sono stampate in questo modo. +@end quotation + +@quotation ATTENZIONE +Note di avviso o raccomandazioni di cautela sono stampate in questo modo. +@end quotation +@end ifset + +@c fakenode --- for prepinfo +@unnumberedsubsec Angoli Bui +@cindex Kernighan, Brian +@quotation +@i{Gli angoli bui sono essenzialmente frattali---per quanto vengano +illuminati, ce n'@`e sempre uno pi@`u piccolo e pi@`u buio.} +@author Brian Kernighan +@end quotation + +@cindex a.b., si veda angolo buio +@cindex angolo buio +Fino allo standard POSIX (e @cite{@value{TITLE}}), +molte caratteristiche di @command{awk} erano poco documentate o +non documentate affatto. Le descrizioni di queste caratteristiche +(chiamate spesso ``angoli bui'') sono segnalate in questo @value{DOCUMENT} con +@iftex +il disegno di una torcia elettrica nel margine, come mostrato qui. +@value{DARKCORNER} +@end iftex +@ifnottex +``(a.b.)''. +@end ifnottex +@ifclear FOR_PRINT +Appaiono anche nell'indice sotto la voce ``angolo buio.'' +@end ifclear + +Ma come osservato nella citazione d'apertura, ogni trattazione degli +angoli bui @`e per definizione incompleta. + +@cindex e.c., si veda estensioni comuni +Estensioni al linguaggio standard di @command{awk} disponibili in pi@`u di una +implementazione di @command{awk} sono segnate +@ifclear FOR_PRINT +``@value{COMMONEXT},'' ed elencate nell'indice sotto ``estensioni comuni'' +e ``comuni, estensioni''. +@end ifclear +@ifset FOR_PRINT +``@value{COMMONEXT}'' per ``estensioni comuni.'' +@end ifset + +@node Storia del manuale +@unnumberedsec Breve storia del Progetto GNU e di questo @value{DOCUMENT} + +@cindex FSF (Free Software Foundation) +@cindex Free Software Foundation (FSF) +@cindex Stallman, Richard +La Free Software Foundation (FSF) @`e un'organizzazione senza scopo di lucro +dedita alla produzione e distribuzione di software liberamente distribuibile. +@`E stata fondata da Richard M.@: Stallman, l'autore della prima versione +dell'editor Emacs. GNU Emacs @`e oggi la versione di Emacs pi@`u largamente usata. + +@cindex Progetto GNU +@cindex GNU, Progetto +@cindex GPL (General Public License) +@cindex General Public License, si veda GPL +@cindex documentazione, online +Il Progetto GNU@footnote{GNU sta per ``GNU's Not Unix.''} +@`e un progetto della Free Software +Foundation in continuo sviluppo per creare un ambiente per computer completo, liberamente +distribuibile, conforme allo standard POSIX. +La FSF usa la GNU General Public License (GPL) per assicurare che +il codice sorgente del loro software sia sempre +disponibile all'utente finale. +@ifclear FOR_PRINT +Una copia della GPL @`e inclusa +@ifnotinfo +in questo @value{DOCUMENT} +@end ifnotinfo +per la consultazione +(@pxref{Copia}). +@end ifclear +La GPL si applica al codice sorgente in linguaggio C per @command{gawk}. +Per saperne di pi@`u sulla FSF e sul Progetto GNU, +si veda @uref{http://www.gnu.org, la pagina principale del Progetto GNU}. +Questo @value{DOCUMENT} si pu@`o leggere anche dal +@uref{http://www.gnu.org/software/gawk/manual/, sito di GNU}. + +@ifclear FOR_PRINT +Una shell, un editor (Emacs), compilatori ottimizzanti C, C++ e +Objective-C altamente portabili, un debugger simbolico e dozzine di grandi e +piccoli programmi di utilit@`a (come @command{gawk}), sono stati completati e +sono liberamente disponibili. Il kernel del sistema operativo GNU (noto come +HURD), @`e stato rilasciato ma @`e ancora allo stato di sviluppo iniziale. + +@cindex Linux +@cindex GNU/Linux +@cindex sistemi operativi basati su BSD +In attesa che il sistema operativo GNU venga pi@`u completatamente +sviluppato, si dovrebbe prendere in considerazione l'uso di GNU/Linux, un +sistema operativo liberamente distribuibile e basato su Unix disponibile +per Intel, Power Architecture, +Sun SPARC, IBM S/390, e altri +sistemi.@footnote{La terminologia ``GNU/Linux'' @`e spiegata +nel @ref{Glossario}.} +Molte distribuzioni GNU/Linux sono +scaricabili da internet. +@end ifclear + +@ifnotinfo +Il @value{DOCUMENT} @`e realmente libero---almeno, l'informazione che contiene +@`e libera per chiunque---. Il codice sorgente del @value{DOCUMENT}, leggibile +elettronicamente, viene fornito con @command{gawk}. +@ifclear FOR_PRINT +(Dare un'occhiata alla Free Documentation +License in @ref{Licenza per Documentazione Libera GNU (FDL)}.) +@end ifclear +@end ifnotinfo + +@cindex Close, Diane +Il @value{DOCUMENT} in s@'e ha gi@`a avuto parecchie edizioni in passato. +Paul Rubin ha scritto la prima bozza di @cite{The GAWK Manual};, che era +lunga una quarantina di pagine. +Diane Close e Richard Stallman l'hanno migliorata arrivando alla +versione che era +lunga una novantina di pagine, e descriveva solo la versione originale +``vecchia'' di @command{awk}. +Ho iniziato a lavorare con quella versione nell'autunno del 1988. +Mentre ci stavo lavorando, +la FSF ha pubblicato parecchie versioni preliminari, numerate 0.@var{x}). +Nel 1996, l'edizione 1.0 fu rilasciata assieme a @command{gawk} 3.0.0. +La FSF ha pubblicato le prime due edizioni col +titolo @cite{GAWK: The GNU Awk User's Guide}. +@ifset FOR_PRINT +SSC ha pubblicato due edizioni del @value{DOCUMENT} col +titolo @cite{Effective awk Programming}, e O'Reilly ha pubblicato +la terza edizione nel 2001 +@end ifset + +Questa edizione mantiene la struttra di base delle edizioni precedenti. +Per l'edizione FSF 4.0, il contenuto era stato accuratamente rivisto +e aggiornato. Tutti i riferimenti a versioni di @command{gawk} anteriori alla +versione 4.0 sono stati eliminati. +Di particolare interesse in quella edizione era l'aggiunta del @ref{Debugger}. + +Per l'edizione FSF +@ifclear FOR_PRINT +@value{EDITION}, +@end ifclear +@ifset FOR_PRINT +@value{EDITION} +(la quarta edizione, come pubblicata da O'Reilly), +@end ifset +il contenuto @`e stato riorganizzato in parti, +e le aggiunte pi@`u importanti sono +@iftex +il +@end iftex +@ref{Calcolo con precisione arbitraria}, e +@iftex +il +@end iftex +@ref{Estensioni dinamiche}. + +Questo @value{DOCUMENT} continuer@`a certamente ad evolversi. Se si trovano +errori nel @value{DOCUMENT}, si prega di segnalarli! @xref{Bug} +per informazioni su come inviare le segnalazione di problemi elettronicamente. +@ifset FOR_PRINT +@node Restare aggiornati +@unnumberedsec Come restare aggiornati + +Potreste avere una versione di @command{gawk} pi@`u recente di quella +descritta qui. Per vedere cosa @`e cambiato, +dovreste prima guardare il file @file{NEWS} nella distribuzione di +@command{gawk}, che fornisce un sommario ad alto livello dei +cambiamenti in ciascuna versione. + +You can then look at the @uref{http://www.gnu.org/software/gawk/manual/, +online version} of this @value{DOCUMENT} to read about any new features. +@end ifset + +@ifclear FOR_PRINT +@node Come contribuire +@unnumberedsec Come collaborare + +Come manutentore di GNU @command{awk}, un tempo pensai che sarei stato in grado +di gestire una raccolta di programmi @command{awk} pubblicamente disponibili e +avevo anche esortato a collaborare. Rendere disponibili le cose su Internet +aiuta a contenere la distribuzione @command{gawk} entro dimensioni gestibili. + +L'iniziale raccolta di materiale, come questo, @`e tuttora disponibile +su @uref{ftp://ftp.freefriends.org/arnold/Awkstuff}. + +Chi fosse @emph{seriamente} interessato a contribuire nell'implementazione +di un sito Internet dedicato ad argomenti riguardanti il +linguaggio @command{awk}, @`e pregato di contattarmi. + +@ignore +Nella speranza di +fare qualcosa di pi@`u esteso, acquisii il dominio @code{awk.info}. + +Tuttavia, mi accorsi che non potevo dedicare abbastanza tempo per la gestione +del codice inviato dai collaboratori: l'archivio non cresceva e il dominio +rimase in disuso per diversi anni. + +Alla fine del 2008, un volontario si assunse il compito di mettere a punto +un sito web collegato ad @command{awk}---@uref{http://awk.info}---e fece un +lavoro molto ben fatto. + +Se qualcuno ha scritto un programma @command{awk} interessante, o un'estensione +a @command{gawk} che vuole condividere col resto del mondo, @`e invitato a +consultare la pagina @uref{http://awk.info/?contribute} per sapere come +inviarlo per contribuire al sito web. + +Mentre scrivo, questo sito @`e in cerca di un responsabile; se qualcuno @`e +interessato mi contatti. +@end ignore + +@ignore +Altri collegamenti: + +http://www.reddit.com/r/linux/comments/dtect/composing_music_in_awk/ +@end ignore +@end ifclear + +@node Ringraziamenti +@unnumberedsec Ringraziamenti + +La bozza iniziale di @cite{The GAWK Manual} riportava i seguenti ringraziamenti: + +@quotation +Molte persone devono essere ringraziate per la loro assistenza nella produzione +di questo manuale. Jay Fenlason ha contribuito con molte idee e programmi di +esempio. Richard Mlynarik e Robert Chassell hanno fatto utili osservazioni +sulle bozze di questo manuale. Lo scritto +@cite{A Supplemental Document for AWK} di John W.@: Pierce, del +Chemistry Department di UC San Diego, fa il punto su diverse questioni rilevanti +sia per l'implementazione di @command{awk} che per questo manuale, che +altrimenti ci sarebbero sfuggite. +@end quotation + +@cindex Stallman, Richard +Vorrei ringraziare Richard M.@: Stallman, per la sua visione di un mondo +migliore e per il suo coraggio nel fondare la FSF e nel dare inizio al +Progetto GNU. + +@ifclear FOR_PRINT +Edizioni precedenti di questo @value{DOCUMENT} riportavano i seguenti +ringraziamenti: +@end ifclear +@ifset FOR_PRINT +La precedente edizione di questo @value{DOCUMENT} riportava +i seguenti ringraziamenti: +@end ifset + +@quotation +Le seguenti persone (in ordine alfabetico) +hanno inviato commenti utili riguardo alle diverse +versioni di questo libro: +Rick Adams, +Dr.@: Nelson H.F. Beebe, +Karl Berry, +Dr.@: Michael Brennan, +Rich Burridge, +Claire Cloutier, +Diane Close, +Scott Deifik, +Christopher (``Topher'') Eliot, +Jeffrey Friedl, +Dr.@: Darrel Hankerson, +Michal Jaegermann, +Dr.@: Richard J.@: LeBlanc, +Michael Lijewski, +Pat Rankin, +Miriam Robbins, +Mary Sheehan, +e +Chuck Toporek. + +@cindex Berry, Karl +@cindex Chassell, Robert J.@: +@c @cindex Texinfo +Robert J.@: Chassell ha dato preziosissimi consigli +sull'uso di Texinfo. +Merita anche un particolare ringraziamento per avermi +convinto a @emph{non} dare a questo @value{DOCUMENT} +il titolo @cite{How to Gawk Politely}. [Un gioco di parole in inglese che pu@`o +significare sia +@cite{Come usare Gawk educatamente} +che @cite{Come curiosare educatamente}]. +Karl Berry ha aiutato in modo significativo con la parte @TeX{} di Texinfo. + +@cindex Hartholz, Marshall +@cindex Hartholz, Elaine +@cindex Schreiber, Bert +@cindex Schreiber, Rita +Vorrei ringraziare Marshall ed Elaine Hartholz di Seattle e il Dr.@: Bert e Rita +Schreiber di Detroit per i lunghi periodi di vacanza trascorsi in tutta +tranquillit@`a in casa loro, che mi hanno permesso di fare importanti progressi +nella scrittura di questo @value{DOCUMENT} e con lo stesso @command{gawk}. + +@cindex Hughes, Phil +Phil Hughes di SSC +ha contribuito in modo molto importante prestandomi il suo portatile col sistema +GNU/Linux, non una volta, ma due, il che mi ha permesso di fare tantissimo lavoro +mentre ero fuori casa. + +@cindex Trueman, David +David Trueman merita un riconoscimento speciale; ha fatto un lavoro da sentinella +durante lo sviluppo di @command{gawk} affinch@'e funzioni bene e senza errori. +Sebbene non sia pi@`u impegnato con @command{gawk}, +lavorare con lui a questo progetto @`e stato un vero piacere. + +@cindex Drepper, Ulrich +@cindex GNITS mailing list +@cindex mailing list, GNITS +Gli intrepidi membri della lista GNITS, con una particolare menzione per Ulrich +Drepper, hanno fornito un aiuto prezioso e commenti per il progetto +delle funzionalit@`a di internazionalizzazione. + +Chuck Toporek, Mary Sheehan, e Claire Cloutier della O'Reilly & Associates hanno +fornito un'assistenza editoriale rilevante per questo @value{DOCUMENT} per la +versione 3.1 di @command{gawk}. +@end quotation + +@cindex Beebe, Nelson H.F.@: +@cindex Buening, Andreas +@cindex Collado, Manuel +@cindex Colombo, Antonio +@cindex Davies, Stephen +@cindex Deifik, Scott +@cindex Demaille, Akim +@cindex G., Daniel Richard +@cindex Hankerson, Darrel +@cindex Jaegermann, Michal +@cindex Kahrs, J@"urgen +@cindex Kasal, Stepan +@cindex Malmberg, John E. +@cindex Pitts, Dave +@cindex Ramey, Chet +@cindex Rankin, Pat +@cindex Schorr, Andrew +@cindex Vinschen, Corinna +@cindex Zaretskii, Eli + +Dr.@: Nelson Beebe, +Andreas Buening, +Dr.@: Manuel Collado, +Antonio Colombo, +Stephen Davies, +Scott Deifik, +Akim Demaille, +Daniel Richard G., +Darrel Hankerson, +Michal Jaegermann, +J@"urgen Kahrs, +Stepan Kasal, +John Malmberg, +Dave Pitts, +Chet Ramey, +Pat Rankin, +Andrew Schorr, +Corinna Vinschen, +ed Eli Zaretskii +(in ordine alfabetico) +costituiscono l'attuale ``gruppo di lavoro sulla portabilit@`a'' di +@command{gawk}. Senza il loro duro lavoro e il loro aiuto, +@command{gawk} non sarebbe stato neanche lontanamente il buon programma che @`e +oggi. @`E stato e continua a essere un piacere lavorare con questo gruppo +di ottimi collaboratori. + +Notevoli contributi di codice e documentazione sono arrivati da +parecchie persone. @xref{Contributori} per l'elenco completo. + +@ifset FOR_PRINT +@cindex Oram, Andy +Grazie ad Andy Oram della O'Reilly Media per aver iniziato +la quarta edizione e per il suo aiuto in corso d'opera. +Grazie a Jasmine Kwityn per il suo lavoro di revisione. +@end ifset + +Grazie a Michael Brennan per le Prefazioni. + +@cindex Duman, Patrice +@cindex Berry, Karl +Grazie a Patrice Dumas per il nuovo programma @command{makeinfo}. +Grazie a Karl Berry, che continua a lavorare per tenere +aggiornato il linguaggio di marcatura Texinfo. + +@cindex Kernighan, Brian +@cindex Brennan, Michael +@cindex Day, Robert P.J.@: +Robert P.J.@: Day, Michael Brennan e Brian Kernighan hanno gentilmente +fatto da revisiori per l'edizione 2015 di questo @value{DOCUMENT}. Le loro +osservazioni hanno contribuito a migliorare la stesura finale. + +Vorrei ringraziare Brian Kernighan per la sua preziosa assistenza durante +la fase di collaudo e di debug di @command{gawk} e +per l'aiuto in corso d'opera e i consigli nel chiarire diversi punti sul +linguaggio. Non avremmo proprio fatto un cos@`{@dotless{i}} buon lavoro su @command{gawk} e +sulla sua documentazione senza il suo aiuto. + +Brian @`e un fuoriclasse sia come programmatore che come autore di manuali +tecnici. @`E mio dovere ringraziarlo (una volta di pi@`u) per la sua costante +amicizia e per essere stato per me un modello da seguire ormai da quasi +30 anni! Averlo come revisiore @`e per me un privilegio eccitante, ma @`e +stata anche un'esperienza che mi ha fatto sentire molto piccolo@enddots{} + +@cindex Robbins, Miriam +@cindex Robbins, Jean +@cindex Robbins, Harry +@cindex D-o +Devo ringraziare la mia meravigliosa moglie, Miriam, per la sua pazienza nel +corso delle molte versioni di questo progetto, per la correzione delle bozze e +per aver condiviso con me il computer. +Vorrei ringraziare i miei genitori per il loro amore, e per la gentilezza con cui +mi hanno cresciuto ed educato. +Infine, devo riconoscere la mia gratitudine a D-o, per le molte opportunit@`a +che mi ha offerto, e anche per i doni che mi ha elargito, con cui trarre +vantaggio da quelle opportunit@`a. +@ifnotdocbook +@sp 2 +@noindent +Arnold Robbins @* +Nof Ayalon @* +Israel @* +Febbraio 2015 +@end ifnotdocbook + +@ifnotinfo +@part @value{PART1}Il Linguaggio @command{awk} +@end ifnotinfo + +@ifdocbook +@part Il Linguaggio @command{awk} + +La Parte I descrive il linguaggio @command{awk} e il programma @command{gawk} +nel dettaglio. Inizia con le nozioni di base, e continua con tutte le +funzionalit@`a di @command{awk}. Sono incluse anche molte, ma non tutte, le +funzionalit@`a di @command{gawk}. Questa parte contiene i +seguenti capitoli: + +@itemize @value{BULLET} +@item +@ref{Per iniziare} + +@item +@ref{Invocare Gawk} + +@item +@ref{Espressioni regolari} + +@item +@ref{Leggere file} + +@item +@ref{Stampare} + +@item +@ref{Espressioni} + +@item +@ref{Modelli e azioni} + +@item +@ref{Vettori} + +@item +@ref{Funzioni} +@end itemize +@end ifdocbook +@node Per iniziare +@chapter Per iniziare con @command{awk} +@c @cindex @dfn{script}, definizione di +@c @cindex rule, definizione di +@c @cindex program, definizione di +@c @cindex basic function of @command{awk} +@cindex @command{awk}, funzione di + +Il compito fondamentale di @command{awk} @`e quello di ricercare righe (o +altre unit@`a di testo) in file che corrispondano a certi criteri di ricerca. +Quando una riga corrisponde a uno dei criteri, @command{awk} esegue su +quella riga le azioni specificate per quel criterio. @command{awk} continua +a elaborare righe in input in questo modo, finch@'e non raggiunge la fine delle +righe nei file in input. + +@cindex @command{awk}, uso di +@cindex linguaggi di programmazione@comma{} guidati-dai-dati/procedurali +@cindex @command{awk}, programmi +I programmi scritti in @command{awk} sono differenti dai programmi scritti +nella maggior parte degli altri linguaggi, +poich@'e i programmi @command{awk} sono @dfn{guidati dai dati} (ovvero, +richiedono di descrivere i dati sui quali si vuole operare, e in seguito +che cosa fare una volta che tali dati siano stati individuati). +La maggior parte degli altri linguaggi sono @dfn{procedurali}; si deve +descrivere, in maniera molto dettagliata, ogni passo che il programma +deve eseguire. Lavorando con linguaggi procedurali, solitamente @`e +molto pi@`u difficile descrivere chiaramente i dati che il programma +deve elaborare. +Per questa ragione i programmi @command{awk} sono spesso piacevolmente +facili da leggere e da scrivere. + +@cindex programma, definizione di +@cindex regola, definizione di +Quando si esegue @command{awk}, va specificato un +@dfn{programma} @command{awk} che +dice ad @command{awk} cosa fare. Il programma consiste di una serie di +@dfn{regole} (pu@`o anche contenere @dfn{definizioni di funzioni}, +una funzionalit@`a avanzata che per ora ignoreremo; +@pxref{Funzioni definite dall'utente}). Ogni regola specifica un +criterio di ricerca e un'azione da effettuare +una volta che viene trovato un record corrispondente. + +Sintatticamente, una regola consiste in un @dfn{criterio di ricerca}, seguito +da una @dfn{azione}. +L'azione @`e racchiusa tra parentesi graffe per separarla dal criterio di +ricerca. +Per separare regole, basta andare a capo. Quindi un programma +@command{awk} ha una struttura simile a questa: + +@example +@var{criterio} @{ @var{azione} @} +@var{criterio} @{ @var{azione} @} +@dots{} +@end example + +@menu +* Eseguire gawk:: Come iniziare a eseguire programmi + @command{gawk}; comprende la sintassi + della riga di comando. +* File dati di esempio:: File di dati di esempio da usare nei + programmi @command{awk} illustrati in + questo @value{DOCUMENT}. +* Molto semplice:: Un esempio molto semplice. +* Due regole:: Un esempio meno semplice di programma + di una riga, che usa due regole. +* Maggiore sofisticazione:: Un esempio pi@`u complesso. +* Istruzioni/Righe:: Suddividere o riunire istruzioni + su [una o pi@`u] righe. +* Altre funzionalit@`a:: Altre funzionalit@`a di @command{awk}. +* Quando:: Quando usare @command{gawk} e quando + usare altre cose. +* Sommario dell'introduzione:: Sommario dell'introduzione. +@end menu + +@node Eseguire gawk +@section Come iniziare a eseguire programmi @command{gawk} + +@cindex programmi @command{awk}, eseguire +Ci sono vari modi di eseguire un programma @command{awk}. Se il programma @`e +corto, @`e pi@`u facile includerlo nel comando con cui si invoca @command{awk}, +cos@`{@dotless{i}}: + +@example +awk '@var{programma}' @var{input-file1} @var{input-file2} @dots{} +@end example + +@cindex riga di comando, formati +Quando il programma @`e lungo, di solito @`e meglio metterlo in un file +ed eseguirlo con un comando come questo: + +@example +awk -f @var{file-di-programma} @var{input-file1} @var{input-file2} @dots{} +@end example + +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} si occupa di entrambe queste modalit@`a insieme +a parecchie varianti di ciascuna di esse. + +@menu +* Monouso:: Eseguire un breve programma + @command{awk} di tipo usa-e-getta. +* Leggere dal terminale:: Senza uso di file in input (input + immesso da tastiera). +* Lunghi:: Mettere programmi @command{awk} + permanenti in file. +* @dfn{Script} eseguibili:: Preparare programmi @command{awk} + da eseguire come @dfn{script}. +* Commenti:: Aggiungere documentazione a programmi + @command{gawk}. +* Protezione:: Ulteriore discussione di problemi + connessi all'uso di apici nella shell. +@end menu + +@node Monouso +@subsection Eseguire un breve programma @command{awk} usa-e-getta + +Una volta acquisita familiarit@`a con @command{awk}, capiter@`a spesso di +preparare semplici +programmi nel momento in cui servono. In questo caso si pu@`o scrivere +il programma come primo argomento del comando @command{awk}, cos@`{@dotless{i}}: + +@example +awk '@var{programma}' @var{input-file1} @var{input-file2} @dots{} +@end example + +@noindent +dove @var{programma} consiste in una serie di criteri di ricerca e di +azioni, come descritto precedentemente. + +@cindex apice singolo (@code{'}) +@cindex @code{'} (apice singolo) +Questo formato di comando chiede alla @dfn{shell}, ossia all'interpretatore +dei comandi, di richiamare @command{awk} e di usare il @var{programma} per +trattare record nei file in input. +Il @var{programma} @`e incluso tra apici in modo che +la shell non interpreti qualche carattere destinato ad @command{awk} come +carattere speciale +della shell. Gli apici fanno inoltre s@`{@dotless{i}} che la shell tratti tutto il +@var{programma} come un solo argomento per @command{awk}, e permettono che +@var{programma} sia pi@`u lungo di una riga. + +@cindex shell, @dfn{script} +@cindex programmi @command{awk}, eseguire, da @dfn{script} di shell +Questo formato @`e utile anche per eseguire programmi @command{awk} di +dimensioni piccole o medie da @dfn{script} di shell, perch@'e non richiede +un file separato che contenga il programma @command{awk}. Uno @dfn{script} +di shell @`e pi@`u affidabile, perch@'e non ci sono altri file che possono +venirsi a trovare fuori posto. + +Pi@`u avanti in questo capitolo, +@iftex +nella +@end iftex +@ifnottex +in +@end ifnottex +@ifdocbook +@value{SECTION} +@end ifdocbook +@ref{Molto semplice}, +si vedranno esempi di parecchi programmi, +brevi, scritti sulla riga di comando. + +@node Leggere dal terminale +@subsection Senza uso di file in input (input immesso da tastiera) + +@cindex standard input +@cindex input, standard +@cindex file in input, eseguire @command{awk} senza usarli +Si pu@`o anche eseguire @command{awk} senza indicare alcun file in input. Se +si immette la seguente riga di comando: + +@example +awk '@var{programma}' +@end example + +@noindent +@command{awk} prende come input del @var{programma} lo @dfn{standard input}, +che di solito significa qualsiasi cosa venga immesso dalla tastiera. +Ci@`o prosegue finch@'e non si segnala una fine-file battendo @kbd{Ctrl-d}. +(In sistemi operativi non-POSIX, il carattere di fine-file pu@`o essere diverso.) + +@cindex input, file in, si veda file in input +@cindex file in input, eseguire @command{awk} senza usarli +@cindex programmi @command{awk}, eseguire, senza file in input +Per esempio, il seguente programma stampa un consiglio da amico +(dalla @cite{Guida galattica per gli autostoppisti} di Douglas Adams ), +per non lasciarsi spaventare dalle complessit@`a della programmazione per +computer: + +@example +$ @kbd{awk 'BEGIN @{ print "Non v\47allarmate!" @}'} +@print{} Non v'allarmate! +@end example + +@command{awk} esegue le istruzioni associate a @code{BEGIN} prima di leggere +qualsiasi input. Se non ci sono altre istruzioni nel proprio programma, come +in questo caso, @command{awk} si ferma, invece di tentare di leggere input che +non sa come elaborare. +Il @samp{\47} @`e un modo straordinario (spiegato pi@`u avanti) per inserire un +apice singolo nel programma, senza dover ricorrere a fastidiosi meccanismi +di protezione della shell. + +@quotation NOTA +Se si usa Bash come shell, si dovrebbe digitare il comando @samp{set +H} prima +eseguire questo programma interattivamente, per non avere una cronologia dei +comandi nello stile della C shell, che tratta il @samp{!} come un carattere +speciale. Si raccomanda di inserire quel comando nel proprio file di +personalizzazione della shell. +@end quotation + +Il seguente semplice programma @command{awk} +emula il comando @command{cat}; ovvero copia qualsiasi cosa si +batta sulla tastiera nel suo standard output (perch@'e succede @`e spiegato fra +poco): + +@example +$ @kbd{awk '@{ print @}'} +@kbd{Ora @`e il tempo per tutti gli uomini buoni} +@print{} Ora @`e il tempo per tutti gli uomini buoni +@kbd{di venire in aiuto al loro paese.} +@print{} di venire in aiuto al loro paese. +@kbd{Or sono sedici lustri e sette anni, ...} +@print{} Or sono sedici lustri e sette anni, ... +@kbd{Cosa, io preoccupato?} +@print{} Cosa, io preoccupato? +@kbd{Ctrl-d} +@end example + +@node Lunghi +@subsection Eseguire programmi lunghi + +@cindex programmi @command{awk}, eseguire +@cindex programmi @command{awk}, lunghi +@cindex file, programmi @command{awk} in +Talora i programmi @command{awk} sono molto lunghi. In tali situazioni +conviene mettere il programma in un file separato. Per dire ad +@command{awk} di usare quel file come programma, digitare: + +@example +awk -f @var{file-sorgente} @var{input-file1} @var{input-file2} @dots{} +@end example + +@cindex @option{-f}, opzione +@cindex riga di comando, opzione @option{-f} +L'opzione @option{-f} dice al comando @command{awk} di ottenere il programma +@command{awk} dal file @var{file-sorgente} (@pxref{Opzioni}). +Ogni @value{FN} pu@`o essere usato come @var{file-sorgente}. Per esempio, si +potrebbe mettere il programma: + +@example +BEGIN @{ print \"Non v'allarmate!\" @} +@end example + +@noindent +nel file @file{consiglio}. Allora questo comando: + +@example +awk -f consiglio +@end example + +@noindent +@`e equivalente al comando: + +@example +awk 'BEGIN @{ print \"Non v\47allarmate!\" @}' +@end example + +@cindex protezione, nella riga di comando di @command{gawk} +@noindent +Questo @`e gi@`a stato spiegato prima +(@pxref{Leggere dal terminale}). +Si noti che normalmente non serve mettere apici singoli nel @value{FN} che si +fornisce con @option{-f}, perch@'e di solito i @value{FNS} non contengono +caratteri che sono speciali per la shell. Si noti che in @file{consiglio}, +il programma @command{awk} non ha dei doppi apici che lo delimitano. I +doppi apici sono necessari solo per programmi scritti direttamente sulla riga +di comando di @command{awk}. +(Inoltre, se il programma si trova in un file, @`e possibile usare un apice +singolo all'interno del programma, invece del magico @samp{\47}.) + +@cindex apice singolo (@code{'}), nella riga di comando di @command{gawk} +@cindex @code{'} (apice singolo), nella riga di comando di @command{gawk} +Per identificare chiaramente un file di programma @command{awk} come tale, +si pu@`o aggiungere il suffisso @file{.awk} al @value{FN}. Ci@`o non +cambia l'esecuzione del programma @command{awk} ma semplifica +la ``manutenzione''. + +@node @dfn{Script} eseguibili +@subsection Programmi @command{awk} da eseguire come @dfn{script} +@cindex programmi @command{awk} +@cindex @code{#} (cancelletto), @code{#!} (@dfn{script} eseguibili) +@cindex Unix, @dfn{script} @command{awk} e +@cindex cancelletto (@code{#}), @code{#!} (@dfn{script} eseguibili) + +Una volta familiarizzato con @command{awk}, si potrebbero scrivere +@dfn{script} che richiamano @command{awk}, usando il meccanismo di +@dfn{script} @samp{#!}. Ci@`o @`e +possibile in molti sistemi operativi.@footnote{Il meccanismo @samp{#!} +funziona nei sistemi +GNU/Linux, in quelli basati su BSD e nei sistemi Unix a pagamento.} +Per esempio, si potrebbe modificare il file @file{consiglio} e farlo divenire: + +@example +#! /bin/awk -f + +BEGIN @{ print \"Non v'allarmate!\" @} +@end example + +@noindent +Dopo aver reso eseguibile questo file (con il comando @command{chmod}), +digitare semplicemente @samp{consiglio} +al prompt della shell e il sistema si preparer@`a a eseguire @command{awk} +come se si fosse digitato @samp{awk -f consiglio}: + +@example +$ @kbd{chmod +x consiglio} +$ @kbd{consiglio} +@print{} Non v'allarmate! +@end example + +@noindent +(Si suppone che la directory corrente sia tra quelle contenute nella variabile +che indica il "percorso" di ricerca [solitamente @code{$PATH}]. In caso +contrario si potrebbe aver bisogno di digitare @samp{./consiglio} nella +shell.) + +@dfn{Script} @command{awk} autocontenuti sono utili se si vuol scrivere un +programma che gli utenti possono richiamare senza dover essere informati che +il programma @`e scritto in @command{awk}. + +@sidebar Comprendere @samp{#!} +@cindex portabilit@`a, @code{#!} (@dfn{script} eseguibili) + +@command{awk} @`e un linguaggio @dfn{interpretato}. Ci@`o significa che il +comando @command{awk} legge il programma dell'utente e poi elabora i dati +secondo le istruzioni contenute nel programma (diversamente da un linguaggio +@dfn{compilato} come il C, dove il programma viene prima compilato in codice +macchina che @`e eseguito direttamente dal processore del sistema). Il +programma di utilit@`a @command{awk} @`e perci@`o chiamato @dfn{interpretatore}. +Molti linguaggi moderni sono interpretati. + +La riga che inizia con @samp{#!} lista l'intero @value{FN} di un +interpretatore +da richiamare, con degli argomenti facoltativi che saranno passati a +quell'interpretatore sulla riga di comando. Il sistema operativo quindi +richiama l'interpretatore con gli argomenti dati e con l'intera lista di +argomenti con cui era stato invocato il programma. Il primo argomento nella +lista @`e l'intero @value{FN} del programma @command{awk}. Il resto della lista +degli argomenti contiene opzioni per @command{awk}, oppure @value{DF}, o +entrambi. (Si noti che in molti sistemi @command{awk} pu@`o essere trovato in +@file{/usr/bin} invece che in @file{/bin}.) + +Alcuni sistemi limitano la lunghezza del nome del programma interpretarore a +32 caratteri. Spesso, si pu@`o rimediare utilizzando un collegamento simbolico. + +Non si dovrebbero mettere altri argomenti oltre al primo nella riga @samp{#!} +dopo il percorso del comando @command{awk}. Non funziona. Il sistema +operativo tratta il resto della riga come un argomento solo, e lo passa ad +@command{awk}. +Cos@`{@dotless{i}} facendo il comportamento sar@`a poco chiaro; con ogni probabilit@`a un +messaggio di errore di qualche tipo da @command{awk}. + +@cindex variabili @code{ARGC}/@code{ARGV}, portabilit@`a e +@cindex portabilit@`a, variabile @code{ARGV} +Infine, il valore di @code{ARGV[0]} +(@pxref{Variabili predefinite}) +pu@`o variare a seconda del sistema operativo. +Alcuni sistemi ci mettono @samp{awk}, altri il nome completo del percorso +di @command{awk} (ad. es. @file{/bin/awk}), e altri ancora mettono il nome +dello @dfn{script} dell'utente (@samp{consiglio}). @value{DARKCORNER} +Non bisogna fidarsi del valore di @code{ARGV[0]} +per ottenere il nome del proprio @dfn{script}. +@end sidebar + +@node Commenti +@subsection Documentare programmi @command{gawk}. +@cindex @code{#} (cancelletto), commentare +@cindex cancelletto (@code{#}), commentare +@cindex commentare +@cindex programmi @command{awk}, documentazione + +Un @dfn{commento} @`e del testo incluso in un programma per aiutare le +persone che lo leggeranno; non @`e parte del programma eseguibile vero e +proprio. I commenti possono spiegare cosa fa il programma e come funziona. +Quasi tutti i linguaggi di programmazione possono contenere commenti, poich@'e +i programmi sono solitamente difficili da comprendere senza di essi. + +Nel linguaggio @command{awk}, un commento inizia con il segno del +cancelletto (@samp{#}) e continua fino alla fine della riga. +Il @samp{#} non deve necessariamente essere il primo carattere della riga. +Il linguaggio @command{awk} ignora il resto di una riga dopo il carattere +cancelletto. +Per esempio, potremmo mettere quel che segue in @file{consiglio}: + +@example +# Questo programma stampa uno scherzoso consiglio amichevole. +# Aiuta a far passare la paura del computer agli utenti novelli. +BEGIN @{ print "Non v'allarmate!" @} +@end example + +Si possono mettere dei commenti nei programmi @command{awk} usa-e-getta da +digitare direttamente da tastiera, ma ci@`o solitmanete non serve molto; il +fine di un commento @`e di aiutare l'utente o qualcun altro a comprendere il +programma, quando lo rilegge in un secondo tempo. + +@cindex protezione, per piccoli programmi awk +@cindex apice singolo (@code{'}), vs.@: apostrofo +@cindex @code{'} (apice singolo), vs.@: apostrofo +@quotation ATTENZIONE +Come detto in +@ref{Monouso}, +si possono includere programmi di dimensioni da piccole a medie tra apici +singoli, per mantenere compatti i propri @dfn{script} di shell +autocontenuti. Nel far questo, @emph{non} bisogna inserire un apostrofo +(ossia un apice singolo) in un commento, (o in qualsiasi altra parte del +vostro programma). La shell interpreta gli apici singoli come delimitatori +di chiusura dell'intero programma. Di conseguenza, solitamente la shell +emette un messaggio riguardo ad apici presenti in numero dispari, e se +@command{awk} viene comunque eseguito, @`e probabile che stampi strani +messaggi di errori di sintassi. +Per esempio, nel caso seguente: + +@example +$ @kbd{awk 'BEGIN @{ print "Ciao" @} # un'idea brillante'} +> +@end example + +La shell considera il secondo apice singolo come delimitatore del testo +precedente, e trova che un nuovo testo tra apici ha inizio verso la fine +della riga di comando. A causa di ci@`o emette una richiesta secondaria di +input, e si mette in attesa di ulteriore input. +Con il comando @command{awk} Unix, se si chiude l'ulteriore stringa tra +apici singoli il risultato @`e il seguente: + +@example +$ @kbd{awk '@{ print "Ciao" @} # un'idea brillante'} +> @kbd{'} +@error{} awk: fatale: non riesco ad aprire file `brillante' +@error{} in lettura (File o directory non esistente) +@end example + +@cindex @code{\} (barra inversa) +@cindex barra inversa (@code{\}) +Mettere una barra inversa prima dell'apice singolo in @samp{un'idea} non +risolverebbe, poich@'e le barre inverse non sono speciali all'interno di apici +singoli. +La prossima @value{SUBSECTION} descrive le regole di protezione della shell. +@end quotation + +@node Protezione +@subsection Uso di apici nella shell. +@cindex shell, uso di apici, regole per + +@menu +* Doppi apici in DOS:: Passaggio di apici in file .BAT Windows. +@end menu + +Per programmi @command{awk} di lunghezza da corta a media spesso conviene +digitare il programma sulla riga di comando @command{awk}. +La maniera migliore per farlo @`e racchiudere l'intero programma tra apici +singoli. +Questo vale sia che si digiti il programma interattivamente su +richiesta della shell, sia che lo si scriva come parte di uno @dfn{script} +di shell di maggiori dimensioni: + +@example +awk '@var{testo del programma}' @var{input-file1} @var{input-file2} @dots{} +@end example + +@cindex shell, uso di apici, regole per +@cindex Bourne shell, uso di apici, regole per la +Quando si lavora con la shell, non guasta avere una conoscenza +di base sulle regole per l'uso di apici nella shell. Le regole +seguenti valgono solo per shell in stile Bourne (come Bash, la +Bourne-Again shell). Se si usa la C shell, si avranno regole differenti. + +Prima di immergerci nelle regole, introduciamo un concetto che ricorre +in tutto questo @value{DOCUMENT}, che @`e quello della stringa @dfn{null}, +o vuota. + +La stringa nulla @`e una variabile, di tipo carattere, che non ha un valore. +In altre parole, @`e vuota. Nei programmi @command{awk} si scrive cos@`{@dotless{i}}: +@code{""}. Nella shell la si pu@`o scrivere usando apici sia singoli +che doppi: @code{""} oppure @code{''}. Sebbena la stringa nulla non contenga +alcun carattere, essa esiste lo stesso. Si consideri questo comando: + +@example +$ @kbd{echo ""} +@end example + +@noindent +Qui, il comando @command{echo} riceve un solo argomento, anche se +quell'argomento non contiene alcun carattere. Nel resto di questo +@value{DOCUMENT}, usiamo indifferentemente i termini @dfn{stringa nulla} +e @dfn{stringa vuota}. Ora, proseguiamo con le regole relative agli apici: + + +@itemize @value{BULLET} +@item +Elementi tra apici possono essere concatenati con elementi non tra apici. +La shell converte il tutto in un singolo argomento da passare +al comando. + +@item +Mettere una barra inversa (@samp{\}) prima di qualsiasi singolo carattere +lo protegge. La shell toglie la barra inversa e passa il carattere +protetto al comando. + +@item +@cindex @code{\} (barra inversa), nei comandi di shell +@cindex barra inversa (@code{\}), nei comandi di shell +@cindex apice singolo (@code{'}), nei comandi di shell +@cindex @code{'} (apice singolo), nei comandi di shell +Gli apici singoli proteggono qualsiasi cosa sia inclusa tra un apice di +apertura e uno di chiusura. +La shell non interpreta il testo protetto, il quale viene passato cos@`{@dotless{i}} com'@`e +al comando. +@`E @emph{impossibile} inserire un apice singolo in un testo racchiuso fra +apici singoli. Potete trovare in +@ref{Commenti} +un esempio di cosa succede se si prova a farlo. + +@item +@cindex doppio apice (@code{"}), nei comandi shell +@cindex @code{"} (doppio apice), nei comandi shell +I doppi apici proteggono la maggior parte di quel che @`e racchiuso tra i +doppi apici di apertura e quelli di chiusura. +La shell effettua almeno la sostituzione di variabili e di comandi +sul testo racchiuso tra doppi apici. +Shell differenti possono fare ulteriori tipi di elaborazione +sul testo racchiuso tra doppi apici. + +Poich@'e alcuni caratteri all'interno di un testo racchiuso tra doppi apici +sono interpretati dalla shell, essi devono essere @dfn{protetti} all'interno +del testo stesso. Sono da tener presenti i caratteri +@samp{$}, @samp{`}, @samp{\}, e @samp{"}, tutti i quali devono essere +preceduti da una barra inversa quando ricorrono all'interno di un testo +racchiuso tra doppi apici, per poter essere passati letteralmente al +programma. (La barra inversa viene tolta prima del passaggio al programma.) +Quindi, l'esempio visto +@ifnotinfo +precedentemente +@end ifnotinfo +in @ref{Leggere dal terminale}: + +@example +awk 'BEGIN @{ print "Non v\47allarmate!" @}' +@end example + +@noindent +si potrebbe scrivere invece cos@`{@dotless{i}}: + +@example +$ @kbd{awk "BEGIN @{ print \"Non v'allarmate!\" @}"} +@print{} Non v'allarmate! +@end example + +@cindex apice singolo (@code{'}), con doppio apice +@cindex @code{'} (apice singolo), con doppio apice +Va notato che l'apice singolo non @`e speciale all'interno di un testo +racchiuso tra doppi apici. + +@item +Le stringhe nulle sono rimosse se presenti come parte di un argomento +non-nullo sulla riga di comando, mentre oggetti esplicitamente nulli +sono mantenuti come tali. +Per esempio, per richiedere che il separatore di campo @code{FS} sia +impostato alla stringa nulla, digitare: + +@example +awk -F "" '@var{programma}' @var{file} # corretto +@end example + +@noindent +@cindex stringa nulla come argomento a @command{gawk}, protezione della +Non @`e invece da usare: + +@example +awk -F"" '@var{programma}' @var{file} # errato! +@end example + +@noindent +Nel secondo caso, @command{awk} tenta di usare il nome del programma come +valore di @code{FS}, e il primo @value{FN} come testo del programma! +Ci@`o come minimo genera un errore di sintassi, e un comportamento confuso nel +caso peggiore. +@end itemize + +@cindex protezione, nella riga di comando di @command{gawk}, trucchi per +Mischiare apici singoli e doppi @`e difficile. Occorre utilizzare +trucchi della shell per gli apici, come questi: + +@example +$ @kbd{awk 'BEGIN @{ print "Questo @`e un apice singolo. <'"'"'>" @}'} +@print{} Questo @`e un apice singolo. <'> +@end example + +@noindent +Questo programma stampa tre stringhe tra apici concatenate tra loro. +La prima e la terza sono rinchiuse tra apici singoli, la seconda tra apici +doppi. + +Quanto sopra pu@`o essere ``semplificato'' cos@`{@dotless{i}}: + +@example +$ @kbd{awk 'BEGIN @{ print "Questo @`e un apice singolo <'\''>" @}'} +@print{} Questo @`e un apice singolo <'> +@end example + +@noindent +A voi la scelta del pi@`u leggibile dei due. + +Un'altra opzione @`e quella di usare doppi apici, proteggendo i doppi apici +inclusi, a livello @command{awk}: + +@example +$ @kbd{awk "BEGIN @{ print \"Questo @`e un apice singolo <'>\" @}"} +@print{} Questo @`e un apice singolo <'> +@end example + +@noindent +Quest'opzione @`e fastidiosa anche perch@'e il doppio apice, la barra inversa e +il simbolo del dollaro sono molto comuni nei programmi @command{awk} pi@`u +avanzati. + +Una terza opzione @`e quella di usare le sequenze ottali equivalenti +(@pxref{Sequenze di protezione}) +per i caratteri +apice singolo e doppio, cos@`{@dotless{i}}: + +@example +$ @kbd{awk 'BEGIN @{ print "Questo @`e un apice singolo <\47>" @}'} +@print{} Questo @`e un apice singolo <'> +$ @kbd{awk 'BEGIN @{ print "Questo @`e un doppio apice <\42>" @}'} +@print{} Questo @`e un doppio apice <"> +@end example + +@noindent +Questo funziona bene, ma sai dovrebbe commentare chiaramente quel che +il testo protetto significa. + +Una quarta possibilit@`a @`e di usare assegnamenti di variabili sulla riga di +comando, cos@`{@dotless{i}}: + +@example +@kbd{$ awk -v sq="'" 'BEGIN @{ print "Questo @`e un apice singolo <" sq ">" @}'} +@print{} Questo @`e un apice singolo <'> +@end example + +(Qui, le due stringhe costanti e il valore di @code{sq} sono concatenati in +un'unica stringa che @`e stampata da @code{print}.) + +Se servono veramente sia gli apici singoli che quelli doppi nel proprio +programma @command{awk}, @`e probabilmente meglio tenerlo in un file separato, +dove la shell non interferisce, e si potr@`a scrivere quello che si vuole. + +@node Doppi apici in DOS +@subsubsection Doppi apici in file .BAT Windows + +@ignore +Date: Wed, 21 May 2008 09:58:43 +0200 (CEST) +From: jeroen.brink@inter.NL.net +Subject: (g)awk "contribution" +To: arnold@skeeve.com +Message-id: <42220.193.172.132.34.1211356723.squirrel@webmail.internl.net> + +Hello Arnold, + +maybe you can help me out. Found your email on the GNU/awk online manual +pages. + +I've searched hard to figure out how, on Windows, to print double quotes. +Couldn't find it in the Quotes area, nor on google or elsewhere. Finally i +figured out how to do this myself. + +How to print all lines in a file surrounded by double quotes (on Windows): + +gawk "{ print \"\042\" $0 \"\042\" }" <file> + +Maybe this is a helpfull tip for other (Windows) gawk users. However, i +don't have a clue as to where to "publish" this tip! Do you? + +Kind regards, + +Jeroen Brink +@end ignore + +Sebbene questo @value{DOCUMENT} in generale si preoccupi solo di sistemi POSIX +e della shell POSIX, il problema che stiamo per vedere emerge abbastanza +spesso presso parecchi utenti, e per questo ne parliamo. + +@cindex Brink, Jeroen +Le ``shell'' nei sistemi Microsoft Windows usaso il carattere doppio apice +per protezione, e rendono difficile o impossibile inserire un carattere +doppio apice in uno @dfn{script} scritto su una riga di comando. +l'esempio che segue, per il quale ringraziamo Jeroen Brink, mostra come +stampare tutte le righe di un file, racchiudendole tra doppi apici: + +@example +gawk "@{ print \"\042\" $0 \"\042\" @}" @var{file} +@end example + + +@node File dati di esempio +@section @value{DDF} per gli esempi + +@cindex input file, esempi +@cindex file di @code{mail-list} +Molti degli esempi in questo @value{DOCUMENT} hanno come input due @value{DF} +di esempio. Il primo, @file{mail-list}, contiene una lista di nomi di +persone, insieme ai loro indirizzi email e a informazioni riguardanti le +persone stesse. +Il secondo @value{DF}, di nome @file{inventory-shipped}, contiene +informazioni riguardo a consegne mensili. In entrambi i file, +ogni riga @`e considerata come un @dfn{record}. + +Nel @file{mail-list}, ogni record contiene il nome di una persona, +il suo numero di telefono, il suo indirizzo email, e un codice che indica +la sua relazione con l'autore della lista. +Le colonne sono allineate usando degli spazi. +Una @samp{A} nell'ultima colonna indica che quella persona @`e un conoscente +[Acquaintance]. Una @samp{F} nell'ultima colonna significa che quella +persona @`e un amico [Friend]. Una @samp{R} vuol dire che quella persona @`e +un parente [Relative]: + +@example +@c system if test ! -d eg ; then mkdir eg ; fi +@c system if test ! -d eg/lib ; then mkdir eg/lib ; fi +@c system if test ! -d eg/data ; then mkdir eg/data ; fi +@c system if test ! -d eg/prog ; then mkdir eg/prog ; fi +@c system if test ! -d eg/misc ; then mkdir eg/misc ; fi +@c file eg/data/mail-list +Amelia 555-5553 amelia.zodiacusque@@gmail.com F +Anthony 555-3412 anthony.asserturo@@hotmail.com A +Becky 555-7685 becky.algebrarum@@gmail.com A +Bill 555-1675 bill.drowning@@hotmail.com A +Broderick 555-0542 broderick.aliquotiens@@yahoo.com R +Camilla 555-2912 camilla.infusarum@@skynet.be R +Fabius 555-1234 fabius.undevicesimus@@ucb.edu F +Julie 555-6699 julie.perscrutabor@@skeeve.com F +Martin 555-6480 martin.codicibus@@hotmail.com A +Samuel 555-3430 samuel.lanceolis@@shu.edu A +Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R +@c endfile +@end example + +@cindex file @code{inventory-shipped} +Il @value{DF} @file{inventory-shipped} contiene +informazioni sulle consegne effettuate durante l'anno. +Ogni record contiene il mese, il numero di contenitori verdi spediti, +il numero di scatole rosse spedite, il numero di borse arancione spedite, +e il numero di pacchetti blu spediti, in quest'ordine. +Ci sono 16 record, relativi ai dodici mesi dello scorso anno e ai primi +quattro mesi dell'anno in corso. +Una riga vuota separa i data relativi a ciascun anno: + +@example +@c file eg/data/inventory-shipped +Jan 13 25 15 115 +Feb 15 32 24 226 +Mar 15 24 34 228 +Apr 31 52 63 420 +May 16 34 29 208 +Jun 31 42 75 492 +Jul 24 34 67 436 +Aug 15 34 47 316 +Sep 13 55 37 277 +Oct 29 54 68 525 +Nov 20 87 82 577 +Dec 17 35 61 401 + +Jan 21 36 64 620 +Feb 26 58 80 652 +Mar 24 75 70 495 +Apr 21 70 74 514 +@c endfile +@end example + +Questi file di esempio sono inclusi nella distribuzione @command{gawk}, +nella directory @file{awklib/eg/data}. + +@node Molto semplice +@section Alcuni esempi molto semplici + +I seguenti comandi eseguono un semplice programma @command{awk} che cerca +nel file in input @file{mail-list} la stringa di caratteri @samp{li} (una +sequenza di caratteri @`e solitamente chiamato una @dfn{stringa}; +il termine @dfn{stringa} @`e basato su un uso linguistico, del tipo +``una stringa di perle'' o ``una stringa di luci decorative''): + +@example +awk '/li/ @{ print $0 @}' mail-list +@end example + +@noindent +Quando si incontra una riga che contiene @samp{li}, la si stampa, perch@'e +@w{@samp{print $0}} significa "stampa la riga corrente". (Lo scrivere solo +@samp{print} ha lo stesso significato, quindi avremmo anche potuto +limitarci a fare cos@`{@dotless{i}}). + +Si sar@`a notato che delle barre (@samp{/}) delimitano la stringa @samp{li} +nel programma @command{awk}. Le barre indicano che @samp{li} @`e il +modello da ricercare. Questo tipo di notazione @`e definita come +@dfn{espressione regolare}, e sar@`a trattata pi@`u avanti in maggior dettaglio +@iftex +(@pxrefil{Espressioni regolari}). +@end iftex +@ifnottex +(@pxref{Espressioni regolari}). +@end ifnottex +Il modello pu@`o corrispondere anche solo a una parte di una parola. +Ci sono +apici singoli che racchiudono il programma @command{awk} in modo che la +shell non interpreti alcuna parte di esso come un carattere speciale della +shell. + +Questo @`e quello che il programma stampa: + +@example +$ @kbd{awk '/li/ @{ print $0 @}' mail-list} +@print{} Amelia 555-5553 amelia.zodiacusque@@gmail.com F +@print{} Broderick 555-0542 broderick.aliquotiens@@yahoo.com R +@print{} Julie 555-6699 julie.perscrutabor@@skeeve.com F +@print{} Samuel 555-3430 samuel.lanceolis@@shu.edu A +@end example + +@cindex azioni, default +@cindex criteri di ricerca, default +In una regola @command{awk}, il criterio di selezione o l'azione possono +essere omessi, ma non entrambi. Se il criterio @`e omesso, l'azione viene +applicata a @emph{ogni} riga dell'input. +Se l'azione viene omessa, per default si stampano tutte le righe che +sono individuate dal criterio di selezione. + +@cindex azioni, omesse +Quindi, si potrebbe omettere l'azione (l'istruzione @code{print} e le +graffe) nell'esempio precedente e il risultato sarebbe lo stesso: +@command{awk} stampa tutte le righe che corrispondono al criterio di +ricerca @samp{li}. Per confronto, omettendo l'istruzione @code{print} ma +lasciando le graffe si richiede un'azione nulla, che non fa nulla (cio@`e non +stampa alcuna riga). + +@cindex programmi @command{awk}, esempi molto corti +Molti programmi @command{awk} pratici sono lunghi solo una o due righe. +Qui sotto troviamo una collezione di programmi utili e corti, per iniziare. +Alcuni di questi programmi contengono elementi del linguaggio che non sono +ancora stati spiegati. (La descrizione del programma fornisce una buona +idea di quel che si vuole ottenere, ma occorre leggere il resto del +@value{DOCUMENT} per divenire esperti in @command{awk}!) +Molti degli esempi usano un @value{DF} di nome @file{data}. Questo serve solo +a indicare la posizione del nome; se questi programmi devono venir usati per +se stessi, sostituire i propri @value{FNS} al posto di @file{data}. +Per futura memoria, si noti che spesso c'@`e pi@`u di un modo per fare qualcosa +in @command{awk}. In un altro momento, si potrebbe tornare a guardare questi +esempi per vedere se si riescono a trovare modi differenti per fare le stesse +cose mostrate qui appresso: + +@itemize @value{BULLET} +@item +Stampare ogni riga lunga pi@`u di 80 caratteri: + +@example +awk 'length($0) > 80' data +@end example + +L'unica regola presente ha un'espressione di relazione come modello +e non ha azione---quindi applica l'azione di default, stampando il record. + +@item +Stampare la lunghezza della riga in input pi@`u lunga: + +@example +awk '@{ if (length($0) > max) max = length($0) @} + END @{ print max @}' data +@end example + +Il codice associato a @code{END} viene eseguito dopo che tutto +l'input @`e stato letto; @`e l'altra faccia della medaglia di @code{BEGIN}. + +@cindex programma @command{expand} +@cindex @command{expand}, programma +@item +Stampare la lunghezza della riga pi@`u lunga in @file{data}: + +@example +expand data | awk '@{ if (x < length($0)) x = length($0) @} + END @{ print "la lunghezza massima di una riga @`e" x @}' +@end example + +Questo esempio @`e leggermente diverso da quello precedente: +l'input @`e l'output del comando @command{expand}, che cambia i TAB +in spazi, in modo che le larghezze confrontate siano quelle che sarebbero +qualora le si stampasse, e non il numero dei caratteri di input su ogni +riga. [il carattere TAB occupa un byte nel file, ma pu@`o generare fino a +otto spazi bianchi in fase di stampa.] + +@item +Stampare ogni riga che abbia almeno un campo: + +@example +awk 'NF > 0' data +@end example + +Questa @`e una maniera facile per eliminare le righe vuote dal file (o +piuttosto, per creare un nuovo file, simile al vecchio, ma nel quale le +linee vuote sono state tolte). + +@item +Stampare sette numeri casuali compresi tra 0 e 100, inclusi: + +@example +awk 'BEGIN @{ for (i = 1; i <= 7; i++) + print int(101 * rand()) @}' +@end example + +@item +Stampare il numero totale di byte usato da un @var{elenco-file}: + +@example +ls -l @var{elenco-file} | awk '@{ x += $5 @} + END @{ print "byte totali: " x @}' +@end example + +@item +Stampare il numero totale di kilobyte usati da @var{elenco-file}: + +@c Don't use \ continuation, not discussed yet +@c Remember that awk does floating point division, +@c no need for (x+1023) / 1024 +@example +ls -l @var{elenco-file} | awk '@{ x += $5 @} + END @{ print "K-byte totali:", x / 1024 @}' +@end example + +@item +Stampare una lista in ordine alfabetico di tutti gli utenti del sistema +[Unix]: + +@example +awk -F: '@{ print $1 @}' /etc/passwd | sort +@end example + +@item +Contare le righe in un file: + +@example +awk 'END @{ print NR @}' data +@end example + +@item +Stampare le righe pari nel @value{DF}: + +@example +awk 'NR % 2 == 0' data +@end example + +Se aveste usato invece l'espressione @samp{NR % 2 == 1}, +il programma avrebbe stampato le righe dispari. +@end itemize + +@node Due regole +@section Un esempio che usa due regole +@cindex programmi @command{awk} + +Il programma @command{awk} legge il file in input una riga alla volta. +Per ogni riga @command{awk} controlla la corrispondenza con ogni regola. +Se viene trovata pi@`u di una corrispondenza, vengono eseguite altrettante +azioni, nell'ordine in cui appaiono nel programma @command{awk}. +Se non viene trovata nessuna corrispondenza, non viene eseguita alcuna azione. + +Dopo aver elaborato tutte le regole che hanno corrispondenza con la riga (e +pu@'o darsi che nessuna corrisponda), @command{awk} legge la riga successiva. Comunque +@pxref{Istruzione next}, +@ifdocbook +e @ref{Istruzione Nextfile}.) +@end ifdocbook +@ifnotdocbook +e anche @pxref{Istruzione nextfile}.) +@end ifnotdocbook +Si prosegue cos@`{@dotless{i}} finch@'e il programma raggiunge la fine del file. +Per esempio, il seguente programma @command{awk} contiene due regole: + +@example +/12/ @{ print $0 @} +/21/ @{ print $0 @} +@end example + +@noindent +La prima regola ha la stringa @samp{12} da cercare e +@samp{print $0} come +azione. La seconda regola ha la +stringa @samp{21} da cercare e ha ancora @samp{print $0} come azione. +L'azione di ciascuna regola @`e racchiusa in una coppia di parentesi graffe. + +Questo programma stampa ogni riga che contiene la stringa +@samp{12} @emph{oppure} la stringa @samp{21}. Se una riga contiene entrambe +le stringhe, @`e stampata due volte, una volta per ogni regola. + +Questo @`e ci@`o che capita se eseguiamo questo programma sui nostri @value{DF}, +@file{mail-list} e @file{inventory-shipped}: + +@example +$ @kbd{awk '/12/ @{ print $0 @}} +> @kbd{/21/ @{ print $0 @}' mail-list inventory-shipped} +@print{} Anthony 555-3412 anthony.asserturo@@hotmail.com A +@print{} Camilla 555-2912 camilla.infusarum@@skynet.be R +@print{} Fabius 555-1234 fabius.undevicesimus@@ucb.edu F +@print{} Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R +@print{} Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R +@print{} Jan 21 36 64 620 +@print{} Apr 21 70 74 514 +@end example + +@noindent +Si noti che la riga che inizia con @samp{Jean-Paul} +nel file @file{mail-list} +@`e stata stampata due volte, una volta per ogni regola. + +@node Maggiore sofisticazione +@section Un esempio pi@`u complesso + +Dopo aver imparato a eseguire alcuni semplici compiti, vediamo cosa possono +fare i tipici programmi @command{awk}. +Questo esempio mostra come @command{awk} pu@`o essere usato per riassumere, +selezionare e riordinare l'output di un altro comando. Sono usate +funzionalit@`a di cui non si @`e ancora parlato, quindi non ci si deve preoccupare +se alcuni dettagli risulteranno oscuri: + +@example +ls -l | awk '$6 == "Nov" @{ somma += $5 @} + END @{ print somma @}' +@end example + +@cindex comando @command{ls} +Questo comando stampa il numero totale di byte in tutti i file contenuti +nella directory corrente, la cui data di modifica @`e novembre (di qualsiasi +anno). La parte @w{@samp{ls -l}} dell'esempio @`e un comando di sistema che +fornisce un elenco dei file in una directory, con anche la dimensione di +ogni file e la data di ultima modifica. Il suo output @`e del tipo: + +@example +-rw-r--r-- 1 arnold user 1933 Nov 7 13:05 Makefile +-rw-r--r-- 1 arnold user 10809 Nov 7 13:03 awk.h +-rw-r--r-- 1 arnold user 983 Apr 13 12:14 awk.tab.h +-rw-r--r-- 1 arnold user 31869 Jun 15 12:20 awkgram.y +-rw-r--r-- 1 arnold user 22414 Nov 7 13:03 awk1.c +-rw-r--r-- 1 arnold user 37455 Nov 7 13:03 awk2.c +-rw-r--r-- 1 arnold user 27511 Dec 9 13:07 awk3.c +-rw-r--r-- 1 arnold user 7989 Nov 7 13:03 awk4.c +@end example + +@noindent +@cindex continuazione di riga, nella C shell +Il primo campo contiene le autorizzazioni di lettura/scrittura [r/w], il +secondo il numero dei collegamenti al file [cio@`e il numero di nomi con cui +il file @`e conosciuto], e il terzo campo identifica il proprietario del file. +Il quarto campo identifica il gruppo a cui appartiene il file. +Il quinto campo contiene la dimensione del file, in byte. +Il sesto, settimo e ottavo campo contengono il mese, il giorno e l'ora, +rispettivamente, in cui il file @`e stato modificato. Infine, il nono campo +contiene il @value{FN}. + +@c @cindex automatic initialization +@cindex inizializzazione automatica +L'espressione @samp{$6 == "Nov"} nel nostro programma @command{awk} controlla +se il sesto campo dell'output di @w{@samp{ls -l}} corrisponda alla stringa +@samp{Nov}. Ogni volta che una riga ha la stringa +@samp{Nov} come suo sesto campo, @command{awk} esegue l'azione +@samp{somma += $5}. Questo aggiunge il quinto campo (la dimensione del file) +alla variabile @code{somma}. Come risultato, quando @command{awk} ha finito +di leggere tutte le righe in input, @code{somma} contiene la somma totale +delle dimensioni dei file che corrispondono al criterio di ricerca. +(Ci@`o funziona contando sul fatto che le variabili @command{awk} sono +automaticamente inizializzate a zero.) + +Dopo che l'ultima riga dell'output di @command{ls} @`e stata elaborata, la +regola @code{END} viene eseguita e viene stampato il valore di @code{somma}. +In questo esempio, il valore di @code{somma} @`e 80600. + +Queste tecniche pi@`u avanzate di @command{awk} sono trattate in +@value{SECTIONS} +successive (@pxref{Panoramica sulle azioni}). Prima di poter passare a una +programmazione pi@`u avanzata con @command{awk}, @`e necessario sapere come +@command{awk} interpreta i file in input e visualizza quelli in output. +Modificando campi e usando l'istruzione @code{print} @`e possibile produrre +dei rapporti molto utili ed esteticamente gradevoli. + +@node Istruzioni/Righe +@section Istruzioni e righe in @command{awk} +@cindex interruzioni di riga +@cindex andare a capo + +Molto spesso, ogni riga di un programma @command{awk} @`e un'istruzione a s@'e +stante o una regola isolata, come: + +@example +awk '/12/ @{ print $0 @} + /21/ @{ print $0 @}' mail-list inventory-shipped +@end example + +@cindex @command{gawk}, andare a capo +Comunque, @command{gawk} ignora i ritorni a capo dopo ognuno di questi +simboli e istruzioni: + +@example +, @{ ? : || && do else +@end example + +@noindent +Un ritorno a capo in ogni altro punto del programma @`e considerato come la +fine di un'istruzione.@footnote{Il @samp{?} e i @samp{:} elencati sopra sono +usati nell'espressione condizionale in tre parti descritta in +@ref{Espressioni condizionali}. +Il cambio di riga dopo @samp{?} e i @samp{:} @`e un'estensione minore in +@command{gawk}; specificando @option{--posix} come opzione +(@pxref{Opzioni}), quest'estensione non @`e valida.} + +@cindex @code{\} (barra inversa), continuazione di riga e +@cindex barra inversa (@code{\}), continuazione di riga e +Volendo dividere una sola istruzione su due righe in un punto in cui +andando a capo sarebbe considerata conclusa, @`e possibile @dfn{continuare} +nella riga successiva terminando la prima riga con un carattere di +barra inversa (@samp{\}). La barra inversa dev'essere l'ultimo carattere +sulla riga, per essere riconosciuto come un carattere di continuazione. +Una barra inversa @`e consentita in ogni parte dell'istruzione, anche in mezzo +a una stringa o a un'espressione regolare. Per esempio: + +@example +awk '/Questa espressione regolare @`e troppo lunga, quindi\ + la continuiamo sulla riga seguente/ @{ print $1 @}' +@end example + +@noindent +@cindex portabilit@`a, continuazione di riga con barra inversa e +Non abbiamo quasi mai usato la continuazione tramite barra inversa nei nostri +programmi di esempio. @command{gawk} non pone limiti alla lunghezza di +una riga, quindi la continuazione tramite barra inversa non @`e mai strettamente +necessaria; serve soltanto a migliorare la leggibilit@`a del programma. +Per la stessa ragione, ma anche per amore di chiarezza, abbiamo tenuto +concise molte istruzioni nei programmi presentati in questo @value{DOCUMENT}. +La continuazione tramite barra inversa @`e molto utile quando il proprio +programma @command{awk} si trova in un file sorgente separato, invece di +essere immesso nella riga di comando. Si noti anche che molte implementazioni +di @command{awk} presentano delle differenze su dove @`e possibile usare +la continuazione tramite barra inversa. Per esempio, potrebbero non +consentire di spezzare una costante di tipo stringa usando la continuazione +tramite barra inversa. Quindi, per ottenere la massima portabilit@`a dei +propri programmi @command{awk}, @`e meglio non spezzare le righe nel +mezzo di un'espressione regolare o di una stringa. +@c 10/2000: gawk, mawk, and current bell labs awk allow it, +@c solaris 2.7 nawk does not. Solaris /usr/xpg4/bin/awk does though! sigh. + +@cindex comando @command{csh} +@cindex barra inversa (@code{\}), continuazione di riga e, in @command{csh} +@cindex @code{\} (barra inversa), continuazione di riga e, in @command{csh} +@quotation ATTENZIONE +@emph{la continuazione tramite barra inversa non funziona come sopra descritto +nella C shell.} Funziona per programmi @command{awk} contenuti in file e +per programmi sulla riga di comando, @emph{ammesso} che si stia usando una +shell conforme a POSIX, come la Unix Bourne shell o Bash. Ma la C shell si +comporta in maniera diversa! In quel caso, occorre usare due barre inverse +consecutive, in fondo alla riga. Si noti anche che quando si usa la C shell +@emph{ogni} andata a capo nel vostro programma @command{awk} deve essere +indicata con una barra inversa. Per esempio: + +@example +% @kbd{awk 'BEGIN @{ \} +? @kbd{ print \\} +? @kbd{ "ciao, mondo" \} +? @kbd{@}'} +@print{} ciao, mondo +@end example + +@noindent +Qui, il @samp{%} e il @samp{?} sono i prompt primario e secondario della +C shell, analogamente a quelli usati nella shell standard @samp{$} e @samp{>}. + +Si confronti l'esempio precedente, come viene scritto in una shell conforme +a POSIX: + +@example +$ @kbd{awk 'BEGIN @{} +> @kbd{print \} +> @kbd{"ciao, mondo"} +> @kbd{@}'} +@print{} ciao, mondo +@end example +@end quotation + +@command{awk} @`e un linguaggio orientato alla riga. L'azione relativa a ogni +regola deve iniziare sulla stessa riga del criterio di selezione. Per avere +criterio di selezione e azione su righe separate, si +@emph{deve} usare la continuazione tramite barra inversa; non si pu@`o fare +diversamente. + +@cindex barra inversa (@code{\}), continuazione di riga, commenti e +@cindex @code{\} (barra inversa), continuazione di riga, commenti e +@cindex commenti, continuazione di riga con barra inversa e i +Un'altra cosa da tener presente @`e che la continuazione tramite barra inversa e +i commenti non possono essere frammisti. Non appena @command{awk} incontra +un @samp{#} che inizia un commento, ignora @emph{tutto} il resto della riga. +Per esempio: + +@example +$ @kbd{gawk 'BEGIN @{ print "Non allarmarti" # una amichevole \} +> @kbd{ regola BEGIN} +> @kbd{@}'} +@error{} gawk: riga com.:2: regola BEGIN +@error{} gawk: riga com.:2: ^ syntax error +@end example + +@noindent +In questo caso, parrebbe che la barra inversa continui il commento sulla riga +successiva. Invece, la combinazione barra inversa-ritorno a capo non viene +per nulla notata, in quanto ``nascosta'' all'interno del commento. Quindi, +il @code{BEGIN} @`e marcato come errore di sintassi. + +@cindex istruzioni multiple +@cindex @code{;} (punto e virgola), separare istruzioni nelle azioni +@cindex punto e virgola (@code{;}), separare istruzioni nelle azioni +Quando le istruzioni @command{awk} all'interno di una regola sono brevi, si +potrebbe metterne pi@`u d'una su una riga sola. Ci@`o @`e possibile separando le +istruzioni con un punto e virgola (@samp{;}). +Questo vale anche per le regole stesse. +Quindi, il programma visto all'inizio di +@ifnotinfo +questa +@end ifnotinfo +@ifinfo +questo +@end ifinfo +@value{SECTION} +poteva essere scritto anche cos@`{@dotless{i}}: + +@example +/12/ @{ print $0 @} ; /21/ @{ print $0 @} +@end example + +@quotation NOTA BENE +La possibilit@`a che pi@`u regole coesistano sulla stessa riga, se sono separate +da un punto e virgola, non esisteva nel linguaggio @command{awk} originale; +@`e stata aggiunta per congruenza con quanto @`e consentito per le istruzioni +all'interno di un'azione. +@end quotation + +@node Altre funzionalit@`a +@section Altre funzionalit@`a di @command{awk} + +@cindex variabili +Il linguaggio @command{awk} mette a disposizione un numero di variabili +@dfn{built-in}, o @dfn{predefinite}, che il programma dell'utente pu@`o usare +per ottenere informazioni da @command{awk}. Ci sono pure altre variabili +che il programma pu@`o impostare, per definire come @command{awk} deve +gestire i dati. + +Inoltre, @command{awk} mette a disposizione parecchie funzioni predefinite +[@dfn{built-in}] per effettuare calcoli di tipo comune e operazioni che +agiscono sulle stringhe di caratteri. +@command{gawk} mette a disposizione funzioni predefinite per gestire le +marcature temporali, per effettuare manipolazioni a livello di bit, per +tradurre stringhe al momento dell'esecuzione del programma +(internazionalizzazione), per determinare qual @`e il tipo di una variabile, +e per ordinare dei vettori. + +Nel seguito della presentazione del linguaggio @command{awk}, saranno +introdotte molte delle variabili e parecchie funzioni. Esse sono +descritte sistematicamente in @ref{Variabili predefinite} e in +@ref{Funzioni}. + +@node Quando +@section Quando usare @command{gawk} + +@cindex @command{awk}, uso di +Ora che abbiamo visto qualcosa di quel che @command{awk} @`e in grado di fare, +ci si potr@`a chiedere come @command{awk} potrebbe tornare utile. Usando +programmi di utilit@`a, criteri di ricerca sofisticati, separatori +di campo, istruzioni aritmetiche, e altri criteri di selezione, @`e possibile +produrre degli output molto pi@`u complessi. Il linguaggio @command{awk} @`e +molto utile per fornire dei tabulati partendo da grandi quantit@`a di dati +grezzi, per esempio riassumendo informazioni dall'output di altri +programmi di utilit@`a come @command{ls}. +(@xref{Maggiore sofisticazione}.) + +I programmi scritti con @command{awk} sono normalmente molto pi@`u +corti dei loro equivalenti in altri linguaggi. Ci@`o rende i programmi +@command{awk} facili da comporre e da utilizzare. Spesso i programmi +@command{awk} possono essere scritti al volo a terminale, usati una volta sola +e buttati via. Poich@'e i programmi @command{awk} sono interpretati, si pu@`o +evitare la (normalmente laboriosa) parte di compilazione nel ciclo tipico +dello sviluppo software, ossia edita-compila-prova-correggi. + +@cindex Brian Kernighan, @command{awk} di +In @command{awk} sono stati scritti programmi complessi, compreso un assembler +completo, pluri-piattaforma per +@ifclear FOR_PRINT +@iftex +microprocessori a 8-bit (@pxrefil{Glossario}, per maggiori informazioni), +@end iftex +@ifnottex +microprocessori a 8-bit (@pxref{Glossario}, per maggiori informazioni), +@end ifnottex +@end ifclear +@ifset FOR_PRINT +microprocessori a 8-bit, +@end ifset +e un assembler di microcodice per un computer dedicato esclusivamente +al linguaggio Prolog. +Le possibilit@`a dell'originale @command{awk} erano messe a dura prova +da programmi di questa complessit@`a, ma le versioni moderne sono pi@`u robuste. + +@cindex programmi @command{awk}, complessi +Se capita di scrivere programmi @command{awk} pi@`u lunghi di, diciamo, +qualche centinaio di righe, si potrebbe considerare la possibilit@`a di usare +un linguaggio di programmazione differente da @command{awk}. +La shell consente di ricercare stringhe ed espressioni regolari; inoltre +consente di usare in maniera efficace i comandi di utilit@`a del sistema. +Python offre un piacevole equilibrio tra la facilit@`a di una programmazione +ad alto livello, e la possibilit@`a di interagire a livello di sistema +operativo.@footnote{Altri linguaggi di @dfn{script} popolari comprendono Ruby +e Perl.} + +@node Sommario dell'introduzione +@section Sommario + +@c FIXME: Review this chapter for summary of builtin functions called. +@itemize @value{BULLET} +@item +I programmi in @command{awk} consistono di coppie di +@var{criterio di ricerca}--@var{azione}. + +@item +Un'@var{azione} senza una @var{condizione di ricerca} viene sempre eseguita. +L'@var{azione} di default per una condizione mancante @`e @samp{@{ print $0 @}}. + +@item +Usare +@samp{awk '@var{programma}' @var{file}} +oppure +@samp{awk -f @var{file-programma} @var{file}} +per eseguire @command{awk}. + +@item +Si pu@`o usare la notazione speciale @samp{#!} nella prima riga per creare +programmi @command{awk} che siano eseguibili direttamente. + +@item +I commenti nei programmi @command{awk} iniziano con @samp{#} e continuano +fino alla fine della stessa riga. + +@item +Prestare attenzione ai problemi con gli apici nei programmi @command{awk} +che facciano parte di uno @dfn{script} della shell (o di un file .BAT di +MS-Windows). + +@item +Si pu@`o usare la continuazione tramite barra inversa per continuare righe di +codice sorgente. Le righe sono continuate automaticamente dopo i simboli +virgola, parentesi aperta, punto interrogativo, punto e virgola, +@samp{||}, @samp{&&}, @code{do} ed @code{else}. +@end itemize +@node Invocare Gawk +@chapter Eseguire @command{awk} e @command{gawk} + +Questo @value{CHAPTER} tratta di come eseguire @command{awk}, delle opzioni da +riga di comando, sia quelle dello standard POSIX che quelle specifiche di +@command{gawk}, e di cosa fanno @command{awk} e @command{gawk} con gli +argomenti che non sono opzioni. +Prosegue poi spiegando come @command{gawk} cerca i file sorgenti, +leggendo lo standard input assieme ad altri file, le variabili d'ambiente di +@command{gawk}, lo stato di ritorno di @command{gawk}, l'uso dei file inclusi, +e opzioni e/o funzionalit@`a obsolete e non documentate. + +Molte delle opzioni e funzionalit@`a qui descritte sono trattate con +maggior dettaglio nei capitoli successivi del @value{DOCUMENT}; gli argomenti +presenti in questo @value{CHAPTER} che al momento non interessano si possono +tranquillamente saltare. + +@menu +* Riga di comando:: Come eseguire @command{awk}. +* Opzioni:: Opzioni sulla riga di comando e loro + significato. +* Altri argomenti:: Nomi dei file in input e assegnamento di + valori a variabili. +* Specificare lo standard input:: Come specificare lo standard input insieme ad + altri file. +* Variabili d'ambiente:: Le variabili d'ambiente usate da + @command{gawk}. +* Codice di ritorno:: Il codice di ritorno all'uscita da + @command{gawk}. +* Includere file:: Come includere altri file nel proprio + programma. +* Caricare librerie condivise:: Caricare librerie condivise nel + proprio programma. +* Parti obsolete:: Opzioni e/o funzionalit@`a obsolete. +* Non documentato:: Opzioni e funzionalit@`a non documentate. +* Sommario invocazione:: Sommario invocazione. +@end menu + +@node Riga di comando +@section Come eseguire @command{awk} +@cindex riga di comando, eseguire @command{awk} da +@cindex @command{awk}, eseguire +@cindex argomenti, riga di comando, eseguire @command{awk} +@cindex opzioni sulla riga di comando, eseguire @command{awk} + +Ci sono due modi di eseguire @command{awk}: con un programma esplicito o con +uno o pi@`u file di programma. Qui @`e mostrata la sintassi di entrambi; le voci +racchiuse tra [@dots{}] sono opzionali: + +@display +@command{awk} [@var{opzioni}] @option{-f} @var{file_di _programma} [@option{--}] @var{file} @dots{} +@command{awk} [@var{opzioni}] [@option{--}] @code{'@var{programma}'} @var{file} @dots{} +@end display + +@cindex GNU, opzioni estese +@cindex estese, opzioni +@cindex opzioni estese +In aggiunta alle tradizionali opzioni di una sola lettera in stile POSIX, +@command{gawk} consente anche le opzioni estese GNU. + +@cindex angolo buio, invocare @command{awk} +@cindex @dfn{lint}, controlli con programma vuoto +@`E possibile invocare @command{awk} con un programma vuoto: + +@example +awk '' file_dati_1 file_dati_2 +@end example + +@cindex @option{--lint}, opzione +@noindent +Fare cos@`{@dotless{i}} ha comunque poco senso; @command{awk} termina +silenziosamente quando viene fornito un programma vuoto. +@value{DARKCORNER} +Se @`e stato specificato @option{--lint} sulla riga di comando, +@command{gawk} emette un avviso che avverte +che il programma @`e vuoto. + +@node Opzioni +@section Opzioni sulla riga di comando +@cindex opzioni sulla riga di comando +@cindex riga di comando, opzioni +@cindex GNU, opzioni estese +@cindex opzioni estese + +Le opzioni sono precedute da un trattino e consistono in un unico carattere. +Le opzioni estese in stile GNU sono precedute da un doppio trattino e +consistono in una parola +chiave. La parola chiave pu@`o essere abbreviata, a condizione che +l'abbreviazione identifichi univocamente l'opzione. Se l'opzione prevede un +argomento, la parola chiave @`e immediatamente seguita da un segno di uguale +(@samp{=}) e dal valore dell'argomento, oppure la parola chiave e il valore +dell'argomento sono separati da spazi. +Se un'opzione con un valore viene immessa pi@`u di una volta, +l'ultimo valore @`e quello che conta. + +@cindex POSIX @command{awk}, opzioni estese GNU e +Ogni opzione estesa di @command{gawk} ha una corrispondente opzione +breve in stile POSIX. +Le opzioni estese e brevi sono +intercambiabili in tutti i contesti. +L'elenco seguente descrive le opzioni richieste dallo standard POSIX: + +@table @code +@item -F @var{fs} +@itemx --field-separator @var{fs} +@cindex @option{-F}, opzione +@cindex @option{--field-separator}, opzione +@cindex @code{FS}, variabile, l'opzione @code{--field-separator} e +Imposta la variabile @code{FS} a @var{fs} +(@pxref{Separatori di campo}). + +@item -f @var{file-sorgente} +@itemx --file @var{file-sorgente} +@cindex @option{-f}, opzione +@cindex @option{--file}, opzione +@cindex @command{awk}, programmi, collocazione dei +Legge il sorgente del programma @command{awk} da @var{file-sorgente} +anzich@'e prenderlo dal primo argomento che non @`e un'opzione. +Quest'opzione pu@`o essere data pi@`u volte; il programma @command{awk} +@`e formato dalla concatenazione del contenuto di ogni +@var{file-sorgente} specificato. + +@item -v @var{var}=@var{val} +@itemx --assign @var{var}=@var{val} +@cindex @option{-v}, opzione +@cindex @option{--assign}, opzione +@cindex variabili, impostazione +Imposta la variabile @var{var} al valore @var{val} @emph{prima} che inizi +l'esecuzione del programma. Tali valori di variabile sono disponibili +all'interno della regola @code{BEGIN} +(@pxref{Altri argomenti}). + +L'opzione @option{-v} pu@`o impostare una sola variabile per volta, ma pu@`o +essere usata pi@`u di una volta, impostando ogni volta una variabile +differente, in questo modo: +@samp{awk @w{-v pippo=1} @w{-v pluto=2} @dots{}}. + +@cindex predefinite, variabili, opzione @code{-v}@comma{} impostare con +@cindex variabili predefinite, impostare con opzione @code{-v} +@quotation ATTENZIONE +Usare @option{-v} per impostare valori di variabili predefinite +pu@`o condurre a risultati sorprendenti. @command{awk} reimposter@`a i +valori di quelle variabili secondo le sue necessit@`a, anche ignorando +eventuali valori iniziali che possono essere stati assegnati. +@end quotation + +@item -W @var{gawk-opt} +@cindex @option{-W}, opzione +Fornisce un'opzione specifica dell'implementazione. Questa @`e la convenzione +POSIX per fornire opzioni specifiche dell'implementazione. +Queste opzioni +hanno anche una corrispondente opzione estesa scritta in stile GNU. +Si noti che le opzioni estese possono essere abbreviate, sempre che +le abbreviazioni siano univoche. +L'elenco completo delle opzioni specifiche di @command{gawk} @`e riportato di +seguito. + +@item -- +@cindex riga di comando, opzioni, fine delle +@cindex opzioni sulla riga di comando, fine delle +Segnale della fine delle opzioni da riga di comando. I seguenti argomenti +non sono trattati come opzioni anche se iniziano con @samp{-}. Questa +interpretazione di @option{--} segue le convenzioni POSIX per l'analisi degli +argomenti. + +@cindex @code{-} (meno), nomi di file che iniziano con +@cindex meno (@code{-}), nomi di file che iniziano con +@`E utile se si hanno @value{FNS} che iniziano con @samp{-}, +o negli @dfn{script} di shell, se si hanno @value{FNS} che devono essere +specificati dall'utente che potrebbero iniziare con @samp{-}. +@`E utile anche per passare opzioni al programma @command{awk}; +si veda @ref{Funzione getopt}. +@end table + +L'elenco che segue descrive le opzioni specifiche di @command{gawk}: + +@c Have to use @asis here to get docbook to come out right. +@table @asis +@item @option{-b} +@itemx @option{--characters-as-bytes} +@cindex @option{-b}, opzione +@cindex @option{--characters-as-bytes}, opzione +Fa s@`{@dotless{i}} che @command{gawk} tratti tutti i dati in input come caratteri di un solo +byte. In aggiunta, tutto l'output scritto con @code{print} o @code{printf} +viene trattato come composto da caratteri contenuti in un solo byte. + +Normalmente, @command{gawk} segue lo standard POSIX e cerca di elaborare i suoi +dati di input in accordo con la localizzazione corrente +(@pxref{Localizzazioni}). +Questo spesso pu@`o comportare la conversione di caratteri multibyte in +caratteri estesi (internamente), e pu@`o +creare problemi o confusione se i dati di input non contengono caratteri +multibyte validi. Quest'opzione @`e una maniera facile di dire a @command{gawk}: +``Gi@`u le mani dai miei dati!''. + +@item @option{-c} +@itemx @option{--traditional} +@cindex @option{-c}, opzione +@cindex @option{--traditional}, opzione +@cindex modalit@`a compatibile di (@command{gawk}), specificare +Specifica la @dfn{modalit@`a di compatibilit@`a}, nella quale le estensioni GNU al +linguaggio @command{awk} sono disabilitate; in questo modo @command{gawk} si +comporta proprio come la versione di BWK @command{awk}. + +@xref{POSIX/GNU}, +che riassume le estensioni. +@ifclear FOR_PRINT +Si veda anche +@ref{Modalit@`a di compatibilit@`a}. +@end ifclear + +@item @option{-C} +@itemx @option{--copyright} +@cindex @option{-C}, opzione +@cindex @option{--copyright}, opzione +@cindex GPL (General Public License), stampare +Stampa la versione ridotta della General Public License ed esce. + +@item @option{-d}[@var{file}] +@itemx @option{--dump-variables}[@code{=}@var{file}] +@cindex @option{-d}, opzione +@cindex @option{--dump-variables}, opzione +@cindex fornire una lista di tutte le variabili del programma +@cindex @file{awkvars.out}, file +@cindex file @file{awkvars.out} +@cindex variabili globali, stampare una lista delle +Stampa una lista ordinata di variabili globali, i loro tipi, e i valori finali +in @var{file}. Se non viene fornito alcun @var{file}, stampa questa lista +in un file chiamato @file{awkvars.out} nella directory corrente. +Non sono consentiti spazi tra @option{-d} e @var{file}, se +@var{file} viene specificato. + +@cindex risoluzione di problemi, refusi@comma{} variabili globali +@cindex problemi, risoluzione di, refusi@comma{} variabili globali +Avere una lista di tutte le variabili globali @`e un buon modo per cercare +refusi nei propri programmi. +Si pu@`o usare quest'opzione anche se si ha un grosso programma con tantissime +funzioni, e si vuol essere sicuri che le funzioni non usino +inavvertitamente variabili globali che sarebbero dovute essere locali +(questo @`e un errore particolarmente facile da fare con nomi di variabile +semplici come @code{i}, @code{j}, etc.). + +@item @option{-D}[@var{file}] +@itemx @option{--debug}[@code{=}@var{file}] +@cindex @option{-D}, opzione +@cindex @option{--debug}, opzione +@cindex @command{awk}, debug, abilitare +Abilita l'esecuzione del debug di programmi @command{awk} +(@pxref{Debugging}). +Per default, il debugger legge i comandi interattivamente dalla tastiera +(standard input). +L'argomento opzionale @var{file} consente di specificare un file con una lista +di comandi per il debugger da eseguire in maniera non interattiva. +Non sono consentiti spazi tra @option{-D} e @var{file}, se +@var{file} viene indicato. + +@item @option{-e} @var{testo-del-programma} +@itemx @option{--source} @var{testo-del-programma} +@cindex @option{-e}, opzione +@cindex @option{--source}, opzione +@cindex codice sorgente, combinare +Fornisce del codice sorgente nel @var{testo-del-programma}. +Quest'opzione consente di combinare il codice sorgente contenuto in file +col codice sorgente immesso sulla riga di comando. +Questo @`e particolarmente utile quando si hanno funzioni di libreria che si +vogliono usare dai programmi da riga di comando +(@pxref{AWKPATH (Variabile)}). + +@item @option{-E} @var{file} +@itemx @option{--exec} @var{file} +@cindex @option{-E}, opzione +@cindex @option{--exec}, opzione +@cindex @command{awk}, programmi, collocazione dei +@cindex CGI, @command{awk} @dfn{script} per +Simile a @option{-f}, legge il testo del programma @command{awk} da +@var{file}. Ci sono due differenze rispetto a @option{-f}: + +@itemize @value{BULLET} +@item +Quest'opzione fa terminare l'elaborazione delle opzioni; qualsiasi +altra cosa sulla riga di comando viene inoltrata direttamente al programma +@command{awk}. + +@item +Le variabili da riga di comando della forma +@samp{@var{var}=@var{value}} non sono ammesse. +@end itemize + +Quest'opzione @`e particolarmente necessaria per le applicazioni World Wide Web +CGI che passano argomenti attraverso le URL; l'uso di quest'opzione impedisce +a un utente malintenzionato (o ad altri) di passare opzioni, assegnamenti o +codice sorgente @command{awk} (con @option{-e}) all'applicazione +CGI.@footnote{per maggiori dettagli, +si veda la Sezione 4.4 di @uref{http://www.ietf.org/rfc/rfc3875, +RFC 3875}. Si veda anche +@uref{http://lists.gnu.org/archive/html/bug-gawk/2014-11/msg00022.html, +note esplicative spedite alla mailing list @command{gawk} bug}.} +Quest'opzione dovrebbe essere usata +con @dfn{script} @samp{#!} +(@pxref{@dfn{Script} eseguibili}), in questo modo: + +@example +#! /usr/local/bin/gawk -E + +@var{il programma awk @`e qui @dots{}} +@end example + +@item @option{-g} +@itemx @option{--gen-pot} +@cindex @option{-g}, opzione +@cindex @option{--gen-pot}, opzione +@cindex portabilit@`a, generare file oggetto +@cindex file oggetto portabili, generare +Analizza il programma sorgente e +genera un file GNU @command{gettext} @dfn{portable object template} sullo +standard output per tutte le costanti di tipo stringa che sono state marcate +come da tradurre. +@xref{Internazionalizzazione}, +per informazioni su quest'opzione. + +@item @option{-h} +@itemx @option{--help} +@cindex @option{-h}, opzione +@cindex @option{--help}, opzione +@cindex GNU, opzioni estese, stampare una lista di +@cindex opzioni, stampare una lista di +@cindex stampa, lista di opzioni +Stampa un messaggio sull'``uso'' riassumendo le opzioni brevi ed estese +accettate da @command{gawk} ed esce. + +@item @option{-i} @var{file-sorgente} +@itemx @option{--include} @var{file-sorgente} +@cindex @option{-i}, opzione +@cindex @option{--include}, opzione +@cindex @command{awk}, programmi, collocazione dei +Legge una libreria di sorgenti @command{awk} da @var{file-sorgente}. +Quest'opzione @`e del tutto equivalente a usare la direttiva @code{@@include} +all'interno del proprio programma. @`E molto simile all'opzione +@option{-f}, ma ci sono due differenze importanti. Primo, quando viene usata +l'opzione @option{-i}, il sorgente del programma non viene caricato se @`e +stato caricato in precedenza, mentre con @option{-f}, @command{gawk} carica +sempre il file. Secondo, poich@'e quest'opzione @`e pensata per essere usata +con librerie di codice, @command{gawk} non riconosce tali file come +costituenti l'input del programma principale. Cos@`{@dotless{i}}, dopo l'elaborazione di +un argomento @option{-i}, @command{gawk} si aspetta di trovare il codice +sorgente principale attraverso l'opzione @option{-f} o sulla riga di comando. + +@item @option{-l} @var{ext} +@itemx @option{--load} @var{ext} +@cindex @option{-l}, opzione +@cindex @option{--load}, opzione +@cindex caricare estensioni +Carica un'estensione dinamica denominata @var{ext}. Le estensioni sono +memorizzate come librerie condivise di sistema. +Quest'opzione ricerca la libreria usando la variabile d'ambiente +@env{AWKLIBPATH}. Il suffisso corretto per la piattaforma in uso verr@`a +fornito per default, perci@`o non @`e necessario specificarlo nel nome +dell'estensione. La routine di inizializzazione dell'estensione dovrebbe +essere denominata @code{dl_load()}. Un'alternativa @`e quella di usare la +direttiva @code{@@load} all'interno del programma per caricare una libreria +condivisa. Questa funzionalit@`a avanzata @`e descritta in dettaglio in +@ref{Estensioni dinamiche}. + +@item @option{-L}[@var{valore}] +@itemx @option{--lint}[@code{=}@var{valore}] +@cindex @option{-l}, opzione +@cindex @option{--lint}, opzione +@cindex @dfn{lint}, controlli, emissione di avvertimenti +@cindex avvertimenti, emissione di +Emette messaggi d'avvertimento relativi a costrutti dubbi o non portabili ad +altre implementazioni di @command{awk}. +Non sono consentiti spazi tra @option{-L} e @var{valore}, se +viene indicato il @var{valore}. +Alcuni avvertimenti vengono emessi quando @command{gawk} legge preliminarmente +il programma. Altri vengono emessi quando il programma viene eseguito. +Con l'argomento opzionale @samp{fatal}, gli avvertimenti @dfn{lint} sono considerati +come errori gravi. Potrebbe essere una misura drastica, per@`o il suo uso +incoragger@`a certamente lo sviluppo di programmi @command{awk} pi@`u corretti. +Con l'argomento opzionale @samp{invalid}, vengono emessi solo gli avvertimenti +relativi a quello che @`e effettivamente non valido (funzionalit@`a non ancora +completamente implementata). + +Alcuni avvertimenti vengono stampati solo una volta, anche se i costrutti dubbi +per i quali vengono emessi avvisi ricorrono diverse volte nel programma +@command{awk}. Perci@`o, nell'eliminazione dei problemi rilevati da +@option{--lint}, bisogna porre attenzione a cercare tutte le occorrenze di ogni +costrutto inappropriato. Siccome i programmi @command{awk} generalmente sono +brevi, questa non @`e un'operazione gravosa. + +@item @option{-M} +@itemx @option{--bignum} +@cindex @option{-M}, opzione +@cindex @option{--bignum}, opzione +Chiede il calcolo con precisione arbitraria sui numeri. Quest'opzione non ha +alcun effetto se @command{gawk} non @`e compilato per l'uso delle librerie GNU +MPFR e MP +(@pxref{Calcolo con precisione arbitraria}). + +@item @option{-n} +@itemx @option{--non-decimal-data} +@cindex @option{-n}, opzione +@cindex @option{--non-decimal-data}, opzione +@cindex esadecimali@comma{} valori, abilitare l'interpretazione di +@cindex ottali@comma{} valori, abilitare l'interpretazione di +@cindex risoluzione di problemi, opzione @code{--non-decimal-data} +Abilita l'interpretazione automatica di valori ottali ed esadecimali +nei dati di input +(@pxref{Dati non decimali}). + +@quotation ATTENZIONE +Quest'opzione pu@`o generare gravi malfunzionamenti nei vecchi programmi. +Usare con cautela. Si noti anche che +quest'opzione potrebbe non essere pi@`u disponibile in una futura versione di +@command{gawk}. +@end quotation + +@item @option{-N} +@itemx @option{--use-lc-numeric} +@cindex @option{-N}, opzione +@cindex @option{--use-lc-numeric}, opzione +Forza l'uso del carattere di separazione decimale della localizzazione +quando analizza i dati in input +(@pxref{Localizzazioni}). + +@item @option{-o}[@var{file}] +@itemx @option{--pretty-print}[@code{=}@var{file}] +@cindex @option{-o}, opzione +@cindex @option{--pretty-print}, opzione +Consente la stampa di una versione formattata elegantemente dei programmi +@command{awk}. Implica l'opzione @option{--no-optimize}. +Per default il programma di output viene creato in un file +chiamato @file{awkprof.out} (@pxref{Profilare}). +L'argomento opzionale @var{file} consente di specificare un +@value{FN} differente per l'output. +Non sono consentiti spazi tra @option{-o} e @var{file}, se +@var{file} viene indicato. + +@quotation NOTA +Nel passato, quest'opzione eseguiva anche il programma. +Ora non @`e pi@`u cos@`{@dotless{i}}. +@end quotation + +@item @option{-O} +@itemx @option{--optimize} +@cindex @option{--optimize}, opzione +@cindex @option{-O}, opzione +Abilita le ottimizzazioni di default nella rappresentazione interna del +programma. Attualmente, questo comprende delle semplificazioni nell'uso +di costanti e l'eliminazione delle code di chiamata nelle funzioni +ricorsive [sostituzione della chiamata di funzione con dei salti +diretti alla funzione]. + +Queste ottimizzazioni sono abilitate per default. +Quest'opzione rimane disponibile per compatibilit@`a all'indietro. +Tuttavia pu@`o essere usata per annullare l'effetto di una precedente +opzione @option{-s} (si veda pi@`u sotto in questa lista). + +@item @option{-p}[@var{file}] +@itemx @option{--profile}[@code{=}@var{file}] +@cindex @option{-p}, opzione +@cindex @option{--profile}, opzione +@cindex @command{awk}, profilatura, abilitare la +Abilita la creazione del profilo di esecuzione di programmi @command{awk} +(@pxref{Profilare}). +Implicitamente viene forzata l'opzione @option{--no-optimize}. +Per default, i profili vengono creati in un file chiamato @file{awkprof.out}. +L'argomento opzionale @var{file} consente di specificare un altro +@value{FN} per il file del profilo. +Non sono consentiti spazi tra @option{-p} e @var{file}, se +viene indicato un @var{file}. + +Il profilo contiene il numero di esecuzioni di ogni istruzione sul margine +sinistro e il conteggio delle chiamate di funzione per ogni funzione. + +@item @option{-P} +@itemx @option{--posix} +@cindex @option{-P}, opzione +@cindex @option{--posix}, opzione +@cindex POSIX, modalit@`a +@cindex @command{gawk}, estensioni@comma{} disabilitare +Opera in modalit@`a POSIX rigorosa. Disabilita tutte le estensioni di +@command{gawk} (proprio come @option{--traditional}) e +disabilita tutte le estensioni non consentite da POSIX. + +@xref{Estensioni comuni}, per un sommario delle estensioni +di @command{gawk} che sono disabilitate da quest'opzione. +Inoltre, +vengono applicate le seguenti +restrizioni: + +@itemize @value{BULLET} + +@cindex ritorno a capo +@cindex spazi vuoti, ritorno a capo invece che +@item +I ritorni a capo non sono consentiti dopo @samp{?} o @samp{:} +(@pxref{Espressioni condizionali}). + + +@cindex @code{FS}, variabile, come carattere TAB +@item +Specificando @samp{-Ft} sulla riga di comando non si imposta il valore +della variabile @code{FS} a un singolo carattere TAB +(@pxref{Separatori di campo}). + +@cindex localizzazione, separatore decimale della +@cindex separatore decimale, carattere, specifico della localizzazione +@item +Il carattere di separatore decimale della localizzazione @`e usato per analizzare +i dati di input +(@pxref{Localizzazioni}). +@end itemize + +@c @cindex automatic warnings +@c @cindex warnings, automatic +@cindex @option{--traditional}, opzione, e opzione @code{--posix} +@cindex @option{--posix}, opzione, e opzione @code{--traditional} +Se si forniscono entrambe le opzioni @option{--traditional} e @option{--posix} +sulla riga di comando, @option{--posix} ha la precedenza. Se vengono fornite +entrambe le opzioni @command{gawk} emette un avviso. + +@item @option{-r} +@itemx @option{--re-interval} +@cindex @option{-r}, opzione +@cindex @option{--re-interval}, opzione +@cindex espressioni regolari, espressioni di intervallo e +Consente le espressioni di intervallo +(@pxref{Operatori di espressioni regolari}) +nelle espressioni regolari. +Questo @`e ora il comportamento di default di @command{gawk}. +Tuttavia, quest'opzione rimane (sia per retrocompatibilit@`a +che per l'uso in combinazione con @option{--traditional}). + +@item @option{-s} +@itemx @option{--no-optimize} +@cindex @option{--no-optimize}, opzione +@cindex opzione @option{--no-optimize} +@cindex @option{-s}, opzione, +@cindex opzione @option{-s} +Disabilita le opzioni di ottimizzazione di default di @command{gawk} +effettuate sulla rappresentazione interna del programma. + +@item @option{-S} +@itemx @option{--sandbox} +@cindex @option{-S}, opzione +@cindex @option{--sandbox}, opzione +@cindex sandbox, modalit@`a +@cindex prova, modalit@`a di +Disabilita la funzione @code{system()}, +la ridirezione dell'input con @code{getline}, +la ridirezione dell'output con @code{print} e @code{printf}, +e le estensioni dinamiche. +@`E particolarmente utile quando si vogliono eseguire @dfn{script} @command{awk} +da sorgenti dubbie e si vuol essere ricuri che gli @dfn{script} non abbiano +accesso al sistema (oltre al @value{DF} di input specificato). + +@item @option{-t} +@itemx @option{--lint-old} +@cindex @option{-L}, opzione +@cindex @option{--lint-old}, opzione +Avvisa su costrutti che non sono disponibili nella versione originale di +@command{awk} dalla versione 7 di Unix +(@pxref{V7/SVR3.1}). + +@item @option{-V} +@itemx @option{--version} +@cindex @option{-V}, opzione +@cindex @option{--version}, opzione +@cindex @command{gawk}, versioni di, informazioni su@comma{} stampa +Stampa informazioni sulla versione di questa specifica copia di @command{gawk}. +Consente di determinare se la copia di @command{gawk} in uso @`e aggiornata +rispetto a quello che @`e attualmente in distribuzione da parte della Free +Software Foundation. +@`E utile anche per la segnalazione di bug +(@pxref{Bug}). +@end table + +Ogni altra opzione, se @`e stato specificato il testo di un programma +@`e contrassegnata come non valida con un messaggio di avvertimento, +altrimenti @`e ignorata. + +@cindex @option{-F}, opzione, opzione @option{-Ft} imposta @code{FS} a TAB +In modalit@`a di compatibilit@`a, come caso particolare, se il valore di @var{fs} +fornito all'opzione @option{-F} @`e @samp{t}, @code{FS} @`e impostata al carattere +TAB (@code{"\t"}). Questo @`e vero solo per @option{--traditional} e non +per @option{--posix} +(@pxref{Separatori di campo}). + +@cindex @option{-f}, opzione, usi multipli +L'opzione @option{-f} pu@`o essere usata pi@`u di una volta nella riga di comando. +In questo caso, @command{awk} legge il sorgente del suo programma da tutti i +file indicati, come se fossere concatenati assieme a formare un unico grande +file. +Questo @`e utile per creare librerie di funzioni di @command{awk}. Queste +funzioni possono venir scritte una volta e in seguito recuperate da una +posizione standard, invece di doverle includere in ogni singolo programma. +L'opzione @option{-i} @`e simile in questo senso. +(Come indicato in +@ref{Sintassi delle definizioni}, +i nomi di funzione devono essere univoci). + +Con @command{awk} standard, le funzioni di libreria si possono ancora usare, +anche se il programma @`e immesso dalla tastiera, +specificando @samp{-f /dev/tty}. Dopo aver scritto il programma, +premere @kbd{Ctrl-d} (il carattere di fine file) per terminarlo. +(Si potrebbe anche usare @samp{-f -} per leggere il sorgente del programma +dallo standard input, ma poi non si potr@`a usare lo standard input come sorgente +di dati). + +Siccome @`e scomodo usare il meccanismo di @command{awk} standard per combinare +file sorgenti e programmi @command{awk} da riga di comando, @command{gawk} +fornisce l'opzione @option{-e}. Questo non richiede di evitare l'uso dello +standard input per immettere codice sorgente; consente di combinare +facilmente codice sorgente da riga di comando e da libreria +(@pxref{AWKPATH (Variabile)}). +Come per @option{-f}, le opzioni @option{-e} e @option{-i} +si possono usare pi@`u volte nella riga di comando. + +@cindex @option{-e}, opzione +Se non sono specificate opzioni @option{-f} o @option{-e}, @command{gawk} +usa il primo argomento che non @`e un'opzione come testo del +codice sorgente del programma. + +@cindex @env{POSIXLY_CORRECT}, variabile d'ambiente +@cindex @dfn{lint}, controlli, variabile d'ambiente @env{POSIXLY_CORRECT} +@cindex POSIX, modalit@`a +Se la variabile d'ambiente @env{POSIXLY_CORRECT} esiste, +@command{gawk} si comporta in modalit@`a POSIX rigorosa, esattamente come se +fosse stata fornita l'opzione @option{--posix}. +Molti programi GNU cercano questa variabile d'ambiente per eliminare +estensioni che confliggono con POSIX, ma @command{gawk} si comporta in modo +diverso: sopprime tutte le estensioni, anche quelle che non confliggono con +POSIX, e funziona rigorosamente in modalit@`a POSIX. +Se viene fornita l'opzione @option{--lint} sulla riga di comando e +@command{gawk} passa alla modalit@`a POSIX a causa di @env{POSIXLY_CORRECT}, +viene emesso un messaggio di avvertimento indicando che @`e attiva la +modalit@`a POSIX. Normalmente questa variabile si imposta nel file di avvio +della shell a livello utente. +Per una shell compatibile con Bourne (come Bash), queste righe andranno +aggiunte nel file @file{.profile} della directory "home" dell'utente: + +@example +POSIXLY_CORRECT=true +export POSIXLY_CORRECT +@end example + +@cindex @command{csh}, comando, variabile d'ambiente @env{POSIXLY_CORRECT} +Per una shell compatibile con C,@footnote{Non raccomandato.} +questa riga andr@`a aggiunta nel file @file{.login} nella directory "home" +dell'utente: + +@example +setenv POSIXLY_CORRECT true +@end example + +@cindex portabilit@`a, variabile d'ambiente @env{POSIXLY_CORRECT} +Avere @env{POSIXLY_CORRECT} impostata non @`e raccomandato per l'uso quotidiano, +ma @`e utile per provare la portabilit@`a dei programmi su altri +ambienti. + +@node Altri argomenti +@section Altri argomenti della riga di comando +@cindex riga di comando, argomenti +@cindex argomenti, riga di comando + +Qualsiasi altro argomento sulla riga di comando @`e trattato normalmente come +file in input da elaborare nell'ordine con cui @`e specificato. Comunque, un +argomento che ha la forma @code{@var{var}=@var{valore}}, assegna +il valore @var{valore} alla variabile @var{var}---non specifica affatto +un file. (Si veda @ref{Opzioni di assegnamento}.) Nel seguente esempio, +@var{count=1} @`e un assegnamento di variabile, non un @value{FN}: + +@example +awk -f programma.awk file1 count=1 file2 +@end example + +@cindex @command{gawk}, variabile @code{ARGIND} in +@cindex @code{ARGIND}, variabile, argomenti da riga di comando +@cindex @code{ARGV}, vettore, indicizzare all'interno di +@cindex @code{ARGC}/@code{ARGV}, variabili, argomenti da riga di comando +Tutti gli argomenti da riga di comando sono resi disponibili al programma +@command{awk} nel vettore @code{ARGV} (@pxref{Variabili predefinite}). Opzioni da +riga di comando e il testo del programma (se presente) sono esclusi da +@code{ARGV}. Tutti gli altri argomenti, compresi gli assegnamenti di +variabile, sono inclusi. Come ogni elemento di @code{ARGV} viene elaborato, +@command{gawk} imposta @code{ARGIND} all'indice in @code{ARGV} +dell'elemento corrente. + +@c FIXME: One day, move the ARGC and ARGV node closer to here. +La modifica di @code{ARGC} e @code{ARGV} nel proprio programma @command{awk} +consente di controllare come @command{awk} elabora i file in input; questo @`e +descritto pi@`u dettagliatamente in @ref{ARGC e ARGV}. + +@cindex file in input, assegnamenti di variabile e +@cindex assegnamenti di variabile e file in input +La distinzione tra argomenti che sono @value{FN} e argomenti di assegnamento +di variabili vien fatta quando @command{awk} deve aprire il successivo file di +input. +A quel punto dell'esecuzione, controlla la variabile @value{FN} per vedere se +@`e piuttosto un assegnamento di variabile; se cos@`{@dotless{i}} @`e, @command{awk} imposta la +variabile invece di leggere un file. + +Dunque, le variabili ricevono effettivamente i valori loro assegnati dopo che +tutti i file precedentemente specificati sono stati letti. In particolare, i +valori delle variabili assegnati in questo modo @emph{non} sono disponibili +all'interno di una regola @code{BEGIN} +(@pxref{BEGIN/END}), +poich@'e tali regole vengono eseguite prima che @command{awk} cominci a +esaminare la lista degli argomenti. + +@cindex angolo buio, sequenze di protezione +I valori delle variabili dati sulla riga di comando sono elaborati per +rimuovere sequenze di protezione (@pxref{Sequenze di protezione}). +@value{DARKCORNER} + +In alcune implementazioni di @command{awk} molto vecchie, quando un +assegnamento di variabile capitava prima di un qualsiasi @value{FN}, +l'assegnamento avveniva @emph{prima} che fosse stata eseguita la regola +@code{BEGIN}. Il comportamento di @command{awk} era in questo modo +ambiguo; alcuni assegnamenti da riga di comando erano disponibili +all'interno della regola @code{BEGIN}, mentre altri no. Sfortunatamente, +alcune applicazioni finivano per essere dipendenti da questa +``funzionalit@`a''. Quando @command{awk} fu modificato per essere pi@`u +coerente, fu aggiunta l'opzione @option{-v} a beneficio delle +applicazioni che dipendevano dal vecchio comportamento. + +La funzionalit@`a dell'assegnamento di variabile @`e molto utile per assegnare +valori a variabili come @code{RS}, @code{OFS}, e @code{ORS}, che controllano i +formati di input e di output, prima di effettuare la scansione dei @value{DF}. +@`E utile anche per effettuare passaggi multipli su un o stesso +@value{DF}. Per esempio: + +@cindex file, passaggi multipli su +@example +awk 'pass == 1 @{ @var{pass 1 stuff} @} + pass == 2 @{ @var{pass 2 stuff} @}' pass=1 mydata pass=2 mydata +@end example + +Una volta disponibile la funzionalit@`a per assegnare una variabile, l'opzione +@option{-F} per impostare il valore di @code{FS} non @`e pi@`u strettamente +necessaria. Rimane per compatibilit@`a all'indietro. + +@node Specificare lo standard input +@section Come specificare lo standard input insieme ad altri file + +Capita spesso di voler leggere lo standard input assieme ad altri file. +Per esempio, leggere un file, leggere lo standard input derivante da una +@dfn{pipe}, e poi leggere un altro file. + +Il modo di indicare lo standard input, con tutte le versioni di @command{awk}, +@`e quello di usare un segno meno o trattino da solo, @samp{-}. Per esempio: + +@example +@var{qualche_comando} | awk -f ilmioprogramma.awk file1 - file2 +@end example + +@noindent +In questo caso, @command{awk} legge prima @file{file1}, poi legge +l'output di @var{qualche_comando}, e infile legge +@file{file2}. + +Si pu@`o anche usare @code{"-"} per indicare lo standard input quando si leggono +i file con @code{getline} (@pxref{Getline file}). + +In aggiunta, @command{gawk} consente di specificare il +@value{FN} speciale @file{/dev/stdin}, sia sulla riga di comando che +quando si usa @code{getline}. +Anche qualche altra versione di @command{awk} include questa funzionalit@`a, +ma non @`e standard. +(Alcuni sistemi operativi prevedono un file @file{/dev/stdin} +nel filesystem; comunque, @command{gawk} elabora sempre +questo @value{FN} per conto suo [ossia non importa se il sistema +operativo rende disponibile il file o no].) + +@node Variabili d'ambiente +@section Le variabili d'ambiente usate da @command{gawk} +@cindex variabili d'ambiente usate da @command{gawk} + +Diverse variabili d'ambiente influiscono sul comportamento +di @command{gawk}. + +@menu +* AWKPATH (Variabile):: Ricerca di programmi @command{awk} + in una lista di directory. +* AWKLIBPATH (Variabile):: Ricerca di librerie condivise + @command{awk} su varie directory. +* Altre variabili d'ambiente:: Le variabili d'ambiente. +@end menu + +@node AWKPATH (Variabile) +@subsection Ricerca di programmi @command{awk} in una lista di directory. +@cindex @env{AWKPATH}, variabile d'ambiente +@cindex directory, ricerca di file sorgente +@cindex percorso di ricerca per file sorgente +@cindex ricerca, percorso di, per file sorgente +@cindex differenze tra @command{awk} e @command{gawk}, variabile d'ambiente @env{AWKPATH} +@ifinfo +Il precedente @value{SECTION} ha descritto come i file di programma di +@command{awk} possono essere specificati sulla riga di comando con +l'opzione @option{-f}. +@end ifinfo +Nella maggior parte delle implementazioni di @command{awk} si deve indicare il +percorso completo di ogni file di programma, a meno che il file non +sia nella directory corrente. Con @command{gawk}, invece, se la +variabile @value{FN} impostata con le opzioni @option{-f} o @option{-i} non +contiene un separatore di directory @samp{/}, @command{gawk} cerca un file con +quel nome in un elenco di directory (chiamato @dfn{percorso di ricerca}), +scorrendole una per una. + +Il percorso di ricerca @`e una stringa di nomi di directory separati da due +punti@footnote{Punti e virgola in MS-Windows.}. @command{gawk} prende +il percorso di ricerca dalla variabile d'ambiente @env{AWKPATH}. Se questa +variabile non esiste, o se ha un come valore la stringa nulla, +@command{gawk} usa un percorso di default (descritto tra poco). + +La funzionalit@`a del percorso di ricerca @`e particolarmente utile per costruire +librerie di funzioni di @command{awk}. I file di libreria possono essere messi +in una directory standard inclusa nel percorso di ricerca +e richiamati sulla riga di comando con un +@value{FN} breve. Altrimenti, si dovrebbe scrivere l'intero @value{FN} per +ciascun file. + +Usando l'opzione @option{-i}, o l'opzione @option{-f}, i programmi di +@command{awk} scritti sulla riga di comando possono usare le funzionalit@`a +contenute nei file di libreria di @command{awk} +@iftex +(@pxrefil{Funzioni di libreria}). +@end iftex +@ifnottex +(@pxref{Funzioni di libreria}). +@end ifnottex +La ricerca del percorso non viene eseguita se @command{gawk} @`e in modalit@`a di +compatibilit@`a, sia con l'opzione @option{--traditional} che con l'opzione +@option{--posix}. +@xref{Opzioni}. + +Se il file del codice sorgente non viene trovato con una prima ricerca, +il percorso viene cercato di nuovo dopo aver aggiunto il suffisso +@samp{.awk} al @value{FN}. + +Il meccanismo di ricerca del percorso di @command{gawk} @`e simile a quello +della shell. +(Si veda @uref{http://www.gnu.org/software/bash/manual/, +@cite{The Bourne-Again SHell manual}}.) +Un elemento nullo nel percorso indica la directory corrente. +(Un elemento nullo @`e indicato iniziando o terminando il percorso con un segno +di @samp{:} oppure mettendo due @samp{:} consecutivi [@samp{::}].) + +@quotation NOTA +Per includere la directory corrente nel percorso di ricerca, si pu@`o +aggiungere @file{.} come un elemento del percorso di ricerca, oppure +inserire un elemento nullo. + +Diverse passate versioni di @command{gawk} avrebbero effettuato anche una +ricerca esplicita nella directory corrente, prima o dopo aver esaminato il +percorso di ricerca. A partire dalla @value{PVERSION} 4.1.2, questo non +vale pi@`u; se si desidera una ricerca nella directory corrente, @`e +necessario aggiungere @file{.} esplicitamente, oppure aggiungendo un +elemento nullo al percorso di ricerca. +@end quotation + +Il valore di default di @env{AWKPATH} @`e +@samp{.:/usr/local/share/awk}.@footnote{La versione di @command{gawk} +che state usando potrebbe usare una directory diversa; ci@`o dipende da come +@command{gawk} @`e stato compilato e installato. La directory effettiva @`e il +valore di @code{$(datadir)} generato quando @`e stato configurato +@command{gawk}. Non @`e comunque il caso di preoccuparsi per questo.} +Poich@'e @file{.} @`e incluso all'inizio, @command{gawk} cerca dapprima nella +directory corrente, e poi in @file{/usr/local/share/awk}. +In pratica, questo vuol dire che solo raramente ci sar@`a bisogno di cambiare +il valore di @env{AWKPATH}. + +@xref{File da usare a inizio sessione}, per informazioni su funzioni che possono +essere di aiuto per gestire la variabile @env{AWKPATH}. + +@command{gawk} memorizza il valore del percorso di ricerca in uso in +@code{ENVIRON["AWKPATH"]}. Questo consente di aver accesso al valore del +percorso di ricerca in uso all'interno di un programma @command{awk}. + +Sebbene la variabile @code{ENVIRON["AWKPATH"]} possa +essere cambiata anche all'interno di +un programma @command{awk}, questo non modifica il comportamento del +programma in esecuzione. Questo comportamento ha una sua logica: la variabile +d'ambiente @env{AWKPATH} @`e usata per trovare i file sorgenti del programma; una +volta che il programma @`e in esecuzione, tutti i file sono stati trovati, +e @command{gawk} non ha pi@`u bisogno di usare @env{AWKPATH}. + +@node AWKLIBPATH (Variabile) +@subsection Ricerca di librerie condivise @command{awk} su varie directory. +@cindex @env{AWKLIBPATH}, variabile d'ambiente +@cindex directory, ricerca di estensioni caricabili +@cindex percorso di ricerca per estensioni +@cindex differenze tra @command{awk} e @command{gawk}, variabile d'ambiente @code{AWKLIBPATH} + +La variabile d'ambiente @env{AWKLIBPATH} @`e simile alla variabile @env{AWKPATH}, +ma @`e usata per ricercare estensioni caricabili (memorizzate come +librerie condivise di sistema) specificate con l'opzione @option{-l}, +anzich@'e file sorgenti. Se l'estensione non viene trovata, il percorso viene +cercato nuovamente dopo aver aggiunto il suffisso per la libreria condivisa +appropriato per la piattaforma. Per esempio, sui sistemi GNU/Linux viene usato +il suffisso @samp{.so}. Il percorso di ricerca specificato @`e usato anche +attraverso la direttiva @code{@@load} +(@pxref{Caricare librerie condivise}). + +Se la variabile d'ambiente @env{AWKLIBPATH} non esiste, o se ha come valore +la stringa nulla, @command{gawk} usa un percorso di ricerca di default; +questo normalmente vale @samp{/usr/local/lib/gawk}, anche se il suo valore +pu@`o essere diverso, a seconda di come @`e stato installato @command{gawk}. + +@xref{File da usare a inizio sessione}, per informazioni su funzioni che possono +essere di aiuto per gestire la variabile @env{AWKPATH}. + +@command{gawk} memorizza il valore del percorso di ricerca in uso in +@code{ENVIRON["AWKLIBPATH"]}. Questo consente di aver accesso al valore del +percorso di ricerca in uso all'interno di un programma @command{awk}. + +@node Altre variabili d'ambiente +@subsection Le variabili d'ambiente. + +Molte altre variabili d'ambiente influenzano il comportamento di +@command{gawk}, ma esse sono pi@`u specializzate. Quelle dell'elenco seguente +sono quelle pi@`u utili agli utenti normali: + +@table @env +@item GAWK_MSEC_SLEEP +Specifica l'intervallo tra due tentativi di riconnessione, +in millisecondi. Sui sistemi che non prevedono +la chiamata di sistema @code{usleep()}, +il valore @`e arrotondato a un numero intero di secondi . + +@item GAWK_READ_TIMEOUT +Specifica per quanto tempo, in millisecondi, @command{gawk} +aspetta l'input prima di emettere un messaggio di errore. + +@item GAWK_SOCK_RETRIES +Controlla il numero di volte che @command{gawk} cerca di +ristabilire una connessione bidirezionale TCP/IP (@dfn{socket}) prima di +rinunciare a farlo. +@xref{Reti TCP/IP}. +Si noti che quando @`e attiva l'opzione di continuazione dopo errori di I/O +(@pxref{Continuazione dopo errori}), +@command{gawk} tenta di aprire un @dfn{socket} TCP/IP soltanto una volta. + +@item POSIXLY_CORRECT +Provoca il passaggio di @command{gawk} alla modalit@`a di compatibilit@`a POSIX, +disabilitando tutte le estensioni tradizionali e GNU. +@xref{Opzioni}. +@end table + +Le variabili d'ambiente nell'elenco che segue sono utili +soprattutto agli sviluppatori di @command{gawk} per il collaudo e la messa +a punto del programma. Sono soggette a cambiamenti. Le variabili sono: + +@table @env +@item AWKBUFSIZE +Questa variabile riguarda solo @command{gawk} installato su sistemi +conformi a POSIX. +Col valore di @samp{exact}, @command{gawk} usa la dimensione di ogni file di +input come dimensione del buffer di memoria da allocare per I/O. Altrimenti, +il valore dovrebbe essere un numero, e @command{gawk} usa questo numero come +dimensione del buffer da allocare. (Quando questa variabile non @`e impostata, +@command{gawk} usa la pi@`u piccola tra le dimensioni del file e la dimensione +del blocco di ``default'', che normalmente @`e la dimensione del blocco I/O +del filesystem). + +@item AWK_HASH +Se questa variabile @`e impostata con un valore di @samp{gst}, @command{gawk} +usa la funzione hash di GNU Smalltalk per gestire i vettori. +Questa funzione pu@`o essere leggermente pi@`u veloce della funzione standard. +@item AWKREADFUNC +Se questa variabile esiste, @command{gawk} legge i file sorgenti una riga per +volta, anzich@'e a blocchi. Questa variabile @`e presente +per problemi di debug su filesystem di sistemi operativi non POSIX, +dove l'I/O @`e elaborato a record, non a blocchi. + +@item GAWK_MSG_SRC +Se questa variabile esiste, @command{gawk} include il @value{FN} e il +numero di riga all'interno del codice sorgente @command{gawk} +dal quale sono stati generati i messaggi di avvertimento o +i messaggi di errore grave. Il suo intento @`e quello di aiutare a isolare +l'origine di un messaggio, poich@'e ci possono essere pi@`u righe di codice che +producono lo stesso messaggio di avvertimento o di errore. + +@item GAWK_LOCALE_DIR +Specifica la posizione dei file oggetto compilati contenenti la traduzione dei +messaggi emessi da @command{gawk} stesso. Questa variabile @`e passata alla +funzione @code{bindtextdomain()} nella fase di partenza di @command{gawk}. + +@item GAWK_NO_DFA +Se questa variabile esiste, @command{gawk} non usa il riconoscitore di +espressioni regolari ASFD [automa a stati finiti deterministico] per i tipi di +test di corrispondenza. Questo pu@`o causare un rallentamento di @command{gawk}. +Il suo intento @`e quello di aiutare a isolare le differenze tra i due +riconoscitori di espressioni regolari che @command{gawk} usa internamente (non +dovrebbero esserci differenze, ma a volte la teoria non coincide con la +pratica). + +@item GAWK_STACKSIZE +Specifica di quanto @command{gawk} dovrebbe accrescere il suo stack di +valutazione interno, all'occorrenza. + +@item INT_CHAIN_MAX +Specifica il numero massimo previsto di elementi che @command{gawk} mantiene +su una catena hash per gestire i vettori indicizzati da numeri interi. + +@item STR_CHAIN_MAX +Specifica il numero massimo previsto di elementi che @command{gawk} mantiene +su una catena hash per gestire i vettori indicizzati da stringhe. + +@item TIDYMEM +Se questa variabile esiste, @command{gawk} usa le chiamate di libreria +@code{mtrace()} della @dfn{GNU C library} per aiutare a scoprire +possibili sprechi di memoria. +@end table + +@node Codice di ritorno +@section Il codice di ritorno all'uscita da @command{gawk} + +@cindex codice di ritorno, di @command{gawk} +@cindex stato d'uscita, di @command{gawk} +Se l'istruzione @code{exit} viene usata con un valore +(@pxref{Istruzione exit}), @command{gawk} termina l'esecuzione con il valore +numerico specificato. + +Altrimenti, se non ci sono stati problemi durante l'esecuzione, +@command{gawk} esce col valore della costante C +@code{EXIT_SUCCESS}, che normalmente @`e zero. + +Se si verifica un errore, @command{gawk} esce col valore della +costante C @code{EXIT_FAILURE}, che normalmente @`e uguale a uno. + +Se @command{gawk} esce a causa di un errore grave, il codice di ritorno +@`e due. Sui sistemi non POSIX questo valore pu@`o essere mappato +a @code{EXIT_FAILURE}. + +@node Includere file +@section Come includere altri file nel proprio programma + +@c Panos Papadopoulos <panos1962@gmail.com> contributed the original +@c text for this section. + +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} descrive una funzionalit@`a disponibile solo in +@command{gawk}. + +@cindex @code{@@include}, direttiva +@cindex direttiva @code{@@include} +@cindex includere file, direttiva @code{@@include} +La direttiva @code{@@include} pu@`o essere usata per leggere file sorgenti +di @command{awk} esterni. Questo d@`a la possibilit@`a di suddividere file +sorgenti di @command{awk} di grandi dimensioni in porzioni pi@`u piccole e pi@`u +maneggevoli, e anche di riutilizzare codice @command{awk} di uso comune +da diversi @dfn{script} @command{awk}. In altre parole, si possono +raggruppare funzioni di @command{awk} usate per eseguire determinati compiti +all'interno di file esterni. Questi file possono essere usati proprio come +librerie di funzioni, usando la direttiva @code{@@include} assieme alla +variabile d'ambiente @env{AWKPATH}. Si noti che i file sorgenti possono +venire inclusi anche usando l'opzione @option{-i}. + +Vediamolo con un esempio. +Iniziamo con due @dfn{script} @command{awk} (banali), che chiameremo +@file{test1} e @file{test2}. Questo @`e lo @dfn{script} @file{test1}: + +@example +BEGIN @{ + print "Questo @`e lo script test1." +@} +@end example + +@noindent +e questo @`e @file{test2}: + +@example +@@include "test1" +BEGIN @{ + print "Questo @`e lo script test2." +@} +@end example + +L'esecuzione di @command{gawk} con @file{test2} +produce il seguente risultato: + +@example +$ @kbd{gawk -f test2} +@print{} Questo @`e lo script test1. +@print{} Questo @`e lo script test2. +@end example + +@command{gawk} esegue lo @dfn{script} @file{test2}, il quale include +@file{test1}, usando la direttiva @code{@@include}. +Cos@`{@dotless{i}}, per includere file sorgenti di @command{awk} esterni, basta usare +@code{@@include} seguito dal nome del file da includere, +racchiuso tra doppi apici. + +@quotation NOTA +Si tenga presente che questo @`e un costrutto del linguaggio e che @value{FN} +non pu@`o essere una variabile di tipo stringa, ma solo una costante di tipo +letterale racchiusa tra doppi apici. +@end quotation + +I file da includere possono essere nidificati; p.es., dato un terzo +@dfn{script}, che chiameremo @file{test3}: + +@example +@@include "test2" +BEGIN @{ + print "Questo @`e lo script test3." +@} +@end example + +@noindent +L'esecuzione di @command{gawk} con lo @dfn{script} @file{test3} produce i +seguenti risultati: + +@example +$ @kbd{gawk -f test3} +@print{} Questo @`e lo script test1. +@print{} Questo @`e lo script test2. +@print{} Questo @`e lo script test3. +@end example + +Il @value{FN}, naturalmente, pu@`o essere un nome di percorso. +Per esempio: + +@example +@@include "../funzioni_di_i_o" +@end example + +@noindent +e: + +@example +@@include "/usr/awklib/network" +@end example + +@noindent +sono entrambi percorsi validi. La variabile d'ambiente @env{AWKPATH} pu@`o +rivestire grande importanza quando si usa @code{@@include}. Le stesse +regole per l'uso della variabile d'ambiente @env{AWKPATH} nelle ricerche +da riga di comando +(@pxref{AWKPATH (Variabile)}) si applicano anche a +@code{@@include}. + +Questo @`e di grande aiuto nella costruzione di librerie di funzioni di +@command{gawk}. Se si ha uno @dfn{script} di grandi dimensioni contenente +utili funzioni @command{awk} di uso comune, lo si pu@`o suddividere in file +di libreria e mettere questi file in una directory dedicata. In seguito si +possono includere queste ``librerie'' usando il percorso completo dei +file, o impostando opportunamente la variabile d'ambiente @env{AWKPATH} e +quindi usando @code{@@include} con la sola parte del percorso completo che +designa il file. Naturalmente, +si possono tenere i file di libreria in pi@`u di una directory; +pi@`u @`e complesso l'ambiente di lavoro, pi@`u +directory possono essere necessarie per organizzare i file da includere. + +Vista la possibilit@`a di specificare opzioni @option{-f} multiple, il +meccanismo @code{@@include} non @`e strettamente necessario. +Comunque, la direttiva @code{@@include} pu@`o essere d'aiuto nel costruire +programmi @command{gawk} autosufficienti, riducendo cos@`{@dotless{i}} la necessit@`a +di scrivere righe di comando complesse e tediose. +In particolare, @code{@@include} @`e molto utile per scrivere @dfn{script} CGI +eseguibili da pagine web. + +Come @`e stato detto in @ref{AWKPATH (Variabile)}, i file sorgenti vengono +sempre cercati nella directory corrente, prima di eseguire la ricerca in +@env{AWKPATH}; questo si applica anche ai file indicati con +@code{@@include}. + +@node Caricare librerie condivise +@section Caricare librerie condivise nel proprio programma + +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} descrive una funzionalit@`a disponibile solo in +@command{gawk}. + +@cindex @code{@@load}, direttiva +@cindex direttiva @code{@@load} +@cindex caricare estensioni, direttiva @code{@@load} +@cindex estensioni, caricamento, direttiva @code{@@load} +La direttiva @code{@@load} pu@`o essere usata per leggere estensioni di +@command{awk} esterne (memorizzate come librerie condivise di sistema). +Questo consente di collegare del codice compilato che pu@`o offrire prestazioni +migliori o dare l'accesso a funzionalit@`a estese non incluse nel linguaggio +@command{awk}. La variabile @env{AWKLIBPATH} viene usata per ricercare +l'estensione. Usare @code{@@load} @'e del tutto equivalente a usare l'opzione da +riga di comando @option{-l}. + +Se l'estensione non viene trovata in @env{AWKLIBPATH}, viene effettuata +un'altra ricerca dopo aver aggiunto al @value{FN} il suffisso della +libreria condivisa comunemente in uso per la piattaforma corrente. Per +esempio, sui sistemi GNU/Linux viene usato il suffisso @samp{.so}: + +@example +$ @kbd{gawk '@@load "ordchr"; BEGIN @{print chr(65)@}'} +@print{} A +@end example + +@noindent +Questo @`e equivalente all'esempio seguente: + +@example +$ @kbd{gawk -lordchr 'BEGIN @{print chr(65)@}'} +@print{} A +@end example + +@noindent +Per l'uso da riga di comando @`e pi@`u conveniente l'opzione @option{-l}, +ma @code{@@load} @`e utile da inserire all'interno di un file sorgente di +@command{awk} che richieda l'accesso a un'estensione. + +@ref{Estensioni dinamiche}, descrive come scrivere estensioni (in C or C++) +che possono essere caricate sia con @code{@@load} che con l'opzione +@option{-l}. @`E anche descritta l'estensione @code{ordchr}. + +@node Parti obsolete +@section Opzioni e/o funzionalit@`a obsolete + +@c update this section for each release! + +@cindex opzioni deprecate +@cindex funzionalit@`a deprecate +@cindex obsolete, funzionalit@`a +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} descrive funzionalit@`a o opzioni da riga di comando +provenienti da precedenti versioni di @command{gawk} che non sono pi@`u +disponibili nella versione corrente, o che sono ancora utilizzabili ma sono +deprecate (ci@`o significa che @emph{non} saranno presenti nella prossima +versione). + +I file speciali relativi ai processi @file{/dev/pid}, @file{/dev/ppid}, +@file{/dev/pgrpid} e @file{/dev/user} erano deprecati, ma ancora disponibili, +in @command{gawk} 3.1. A partire dalla @value{PVERSION} 4.0, non sono +pi@`u interpretati da @command{gawk} in modo speciale (al loro posto usare +invece @code{PROCINFO}; si veda @ref{Variabili auto-assegnate}). + +@ignore +This @value{SECTION} +is thus essentially a place holder, +in case some option becomes obsolete in a future version of @command{gawk}. +@end ignore + +@node Non documentato +@section Opzioni e funzionalit@`a non documentate +@cindex non documentate, funzionalit@`a +@cindex funzionalit@`a non documentate +@cindex Skywalker, Luke +@cindex Kenobi, Obi-Wan +@cindex Jedi, Cavalieri +@cindex Cavalieri Jedi +@quotation +@i{Usa il codice sorgente, Luke!} +@author Obi-Wan +@end quotation + +@cindex conchiglie, mare +@ifnotinfo +Questa @value{SECTION} @`e stata lasciata intenzionalmente vuota. +@end ifnotinfo +@ifinfo +Questo @value{SECTION} @`e stato lasciato intenzionalmente vuoto. +@end ifinfo + +@ignore +@c If these came out in the Info file or TeX document, then they wouldn't +@c be undocumented, would they? + +@command{gawk} ha un'opzione non documentata: + +@table @code +@item -W nostalgia +@itemx --nostalgia +Stampa il messaggio @samp{awk: bailing out near line 1} e termina +con un errore grave. +Quest'opzione @`e stata ispirata dal comportamento comune delle primissime +versioni di @command{awk} Unix e da una maglietta [con la scritta]. +Il messaggio @emph{NON} viene tradotto in ambienti non inglesi. +@c so there! nyah, nyah. +@end table + +Le prime versioni di @command{awk} non richiedevano alcun separatore (a capo + +o @samp{;}) tra le regole nei programmi @command{awk}. Quindi, +era normale vedere programmi di una riga come: + +@example +awk '@{ sum += $1 @} END @{ print sum @}' +@end example + +@command{gawk} in realt@`a consente questo stile, ma la cosa non @`e +documentata per non incoraggiare la pratica. Il modo corretto per scrivere +quel programma @`e uno dei +seguenti: + +@example +awk '@{ sum += $1 @} ; END @{ print sum @}' +@end example + +@noindent +oppure: + +@example +awk '@{ sum += $1 @} + END @{ print sum @}' data +@end example + +@noindent +@xref{Istruzioni/Righe}, per una spiegazione pi@`u ampia. + +Si possono inserire righe bianche dopo @samp{;} nei cicli @code{for}. +Questa sembre essere stata una funzionalit@`a a lungo non documentata in +@command{awk} Unix. + +Analogamente, si possono usare istruzioni @code{print} o @code{printf} +nelle parti @var{valore-iniziale} e @var{incremento} di un ciclo +@code{for}. Questa @`e un'altra funzionalit@`a a lungo non documentata in +@command{awk} Unix. + +@command{gawk} consente di usare come nomi di parametro dei +nomi di funzioni predefinite che facciano parte delle estensioni +@command{gawk}, all'interno di funzioni definite dall'utente. +Questo avviene per ``salvaguardare per il futuro'' vecchi programmi che +utilizzino nomi di funzioni aggiunte da @command{gawk} dopo che questi +programmi erano stati scritti. +Le funzioni predefinite standard di command{awk}, per esempio +@code{sin()} o @code{substr()} @emph{non} ammettono questa possibilit@`a. + +Il vettore @code{PROCINFO["argv"]} contiene tutti gli argomenti della +riga di comando (una volta espansi i metacaratteri ed elaborata la +ridirezione, nelle piattaforme in cui ci@`o dev'essere fatto manualmente +dal programma), con indici che vanno da 0 as @code{argc} @minus{} 1. +Per esempio, @code{PROCINFO["argv"][0]} conterr@`a il nome con cui @`e +stato invocato @command{gawk}. L'esempio seguente mostra come @`e +possibile usare questa funzionalit@`a: + +@example +awk ' +BEGIN @{ + for (i = 0; i < length(PROCINFO["argv"]); i++) + print i, PROCINFO["argv"][i] +@}' +@end example + +@`E da tener presente che questo vettore @`e diverso dal vettore +standard @code{ARGV} che non comprende quegli argomenti della riga di +comando che sono gi@`a stati elaborati da +@command{gawk} (@pxref{ARGC e ARGV}). + +@end ignore + +@node Sommario invocazione +@section Sommario + +@itemize @value{BULLET} +@item +Per eseguire @command{awk} usare, o +@samp{awk '@var{programma}' @var{file}} +o +@samp{awk -f @var{file-del-programma} @var{file}}. + +@item +Le tre opzioni standard per tutte le versioni di @command{awk} sono +@option{-f}, @option{-F} e @option{-v}. @command{gawk} fornisce queste e +molte altre, come pure le opzioni estese corrispondenti scritte in stile GNU. + +@item +Gli argomenti da riga di comando che non sono opzioni sono trattati normalmente +come @value{FNS}, a meno che non abbiano la forma @samp{@var{var}=@var{valore}}; +nel qual caso vengono riconosciuti come assegnamenti di variabile da eseguire +in quel punto +nell'elaborazione dell'input. + +@item +Tutti gli argomenti da riga di comando che non sono opzioni, escluso il testo +del programma, vengono messe nel vettore @code{ARGV}. Modifiche a @code{ARGC} +e @code{ARGV} influiscono su come @command{awk} elabora l'input. + +@item +Si pu@`o usare un segno meno a s@'e stante (@samp{-}) per designare lo standard +input sulla riga di comando. @command{gawk} consente anche di usare il +@value{FN} speciale @file{/dev/stdin}. + + +@item +@command{gawk} tiene conto di diverse variabili d'ambiente; +@env{AWKPATH}, @env{AWKLIBPATH} e @env{POSIXLY_CORRECT} sono le +pi@`u importanti. + +@item +Lo stato d'uscita di @command{gawk} invia informazioni al programma che lo +ha invocato. Usare l'istruzione @code{exit} dall'interno di un programma +@command{awk} per impostare il codice di ritorno. + +@item +@command{gawk} consente di includere nel proprio programma file sorgenti di +@command{awk} con la direttiva @code{@@include} o con le opzioni da riga di +comando @option{-i} e @option{-f}. + +@item +@command{gawk} consente di caricare funzioni aggiuntive scritte in C +o C++ con la direttiva @code{@@load} e/o con l'opzione @option{-l} +(questa funzionalit@`a avanzata @`e descritta pi@`u avanti, in +@ref{Estensioni dinamiche}). +@end itemize +@node Espressioni regolari +@chapter Espressioni regolari +@cindex @dfn{regexp} +@cindex espressioni regolari + +Una @dfn{espressione regolare}, o @dfn{regexp}, @`e un modo per descrivere un +insieme di stringhe. +Poich@'e le espressioni regolari sono una parte fondamentale della +programmazione in @command{awk}, il loro formato e il loro uso meritano un +@value{CHAPTER} a s@'e stante. + +@cindex barra (@code{/}), per delimitare le espressioni regolari +@cindex @code{/} (barra), per delimitare le espressioni regolari +Un'espressione regolare racchiusa tra barre (@samp{/}) +@`e un modello di ricerca @command{awk} che individua tutti i record in input +il cui testo corrisponde al modello stesso. +L'espressione regolare pi@`u semplice @`e una sequenza di lettere o di numeri, o +di entrambi. Una tale @dfn{regexp} individua ogni stringa che contenga quella +particolare sequenza. +Quindi, la @dfn{regexp} @samp{pippo} individua ogni stringa che contenga +@samp{pippo}. In altre parole, al modello di ricerca @code{/pippo/} corrisponde +ogni record in input che contiene i cinque caratteri consecutivi @samp{pippo} +@emph{in qualsiasi parte} del record. Altri tipi di @dfn{regexp} permettono +di specificare classi di stringhe molto pi@`u complesse. + +@ifnotinfo +All'inizio, gli esempi in questo @value{CHAPTER} sono semplici. +Man mano che entriamo nei dettagli su +come funzionano le espressioni regolari utilizzeremo formulazioni pi@`u +complesse. +@end ifnotinfo + +@menu +* Uso di @dfn{regexp}:: Come usare le espressioni regolari. +* Sequenze di protezione:: Come scrivere caratteri non stampabili. +* Operatori di espressioni regolari:: Operatori di espressioni regolari. +* Espressioni tra parentesi quadre:: Cosa possono contenere @samp{[...]}. +* Pi@`u lungo da sinistra:: Quanto @`e lungo il testo individuato. +* Espressioni regolari calcolate:: Usare @dfn{regexp} dinamiche. +* Operatori di @dfn{regexp} GNU:: Operatori propri del software GNU. +* Maiuscolo-Minuscolo:: Fare confronti ignorando + maiuscolo/minuscolo. +* Sommario espressioni regolari:: Sommario delle espressioni regolari. +@end menu + +@node Uso di @dfn{regexp} +@section Uso di espressioni regolari + +@cindex espressioni regolari, come criteri di ricerca +Un'espressione regolare pu@`o essere usata come modello di ricerca +racchiudendola tra barre. L'espressione regolare @`e quindi confrontata +con tutto il testo di ogni record (normalmente, basta che corrisponda a +una parte qualsiasi del testo per risultare soddisfatta). Per esempio, +il seguente programma stampa il secondo campo di ogni record in cui compaia +la stringa @samp{li}, in qualsiasi parte del record: + +@example +$ @kbd{awk '/li/ @{ print $2 @}' mail-list} +@print{} 555-5553 +@print{} 555-0542 +@print{} 555-6699 +@print{} 555-3430 +@end example + +@cindex espressioni regolari, operatori +@cindex operatori, ricerca in stringhe +@c @cindex operators, @code{~} +@cindex ricerca in stringhe, operatori +@cindex @code{~} (tilde), operatore @code{~} +@cindex tilde (@code{~}), operatore @code{~} +@cindex @code{!} (punto esclamativo), operatore @code{!~} +@cindex punto esclamativo (@code{!}), operatore @code{!~} +@c @cindex operatori, @code{!~} +@cindex @code{if}, istruzione, uso di espressioni regolari in +@cindex @code{while}, istruzione, uso di espressioni regolari in +@cindex @code{do}-@code{while}, istruzione, uso di espressioni regolari in +@c @cindex istruzione @code{if} +@c @cindex istruzione @code{while} +@c @cindex istruzione @code{do} +Espressioni regolari possono anche essere usate in espressioni di confronto. +Queste espressioni consentono di specificare le stringhe da riconoscere; +non devono necessariamente comprendere l'intero record corrente. I due +operatori @samp{~} e @samp{!~} confrontano espressioni regolari. Le +espressioni che usano questi operatori possono essere usate come modelli di +ricerca, o nelle istruzioni @code{if}, @code{while}, @code{for}, e @code{do}. +(@xref{Istruzioni}.) +Per esempio: + +@example +@var{exp} ~ /@var{regexp}/ +@end example + +@noindent +@`e verificata se l'espressione @var{exp} (intesa come stringa) +corrisponde a @var{regexp}. L'esempio che segue individua, o sceglie, +tutti i record in input in cui la lettera maiuscola @samp{J} @`e presente da +qualche parte nel primo campo: + +@example +$ @kbd{awk '$1 ~ /J/' inventory-shipped} +@print{} Jan 13 25 15 115 +@print{} Jun 31 42 75 492 +@print{} Jul 24 34 67 436 +@print{} Jan 21 36 64 620 +@end example + +Lo stesso risultato si pu@`o ottenere anche cos@`{@dotless{i}}: + +@example +awk '@{ if ($1 ~ /J/) print @}' inventory-shipped +@end example + +Il prossimo esempio chiede che l'espressione @var{exp} +(intesa come stringa) +@emph{NON} corrisponda a @var{regexp}: + +@example +@var{exp} !~ /@var{regexp}/ +@end example + +L'esempio che segue individua o sceglie tutti i record in input il cui +primo campo @emph{NON} contiene +la lettera maiuscola @samp{J}: + +@example +$ @kbd{awk '$1 !~ /J/' inventory-shipped} +@print{} Feb 15 32 24 226 +@print{} Mar 15 24 34 228 +@print{} Apr 31 52 63 420 +@print{} May 16 34 29 208 +@dots{} +@end example + +@cindex @dfn{regexp}, costanti +@cindex costanti @dfn{regexp} +@cindex espressioni regolari, costanti, si veda costanti @dfn{regexp} +Quando una @dfn{regexp} @`e racchiusa tra barre, come @code{/pippo/}, la chiamiamo +una @dfn{costante regexp}, proprio come @code{5.27} @`e una costante +numerica e @code{"pippo"} @`e una costante [di tipo] stringa. + +@node Sequenze di protezione +@section Sequenze di protezione + +@cindex sequenze di protezione, in stringhe +@cindex barra inversa (@code{\}), in sequenze di protezione +@cindex @code{\} (barra inversa), in sequenze di protezione +Alcuni caratteri non possono essere inclusi letteralmente in costanti +stringa (@code{"pippo"}) o in costanti @dfn{regexp} (@code{/pippo/}). +Vanno invece rappresentati usando @dfn{sequenze di protezione}, +ossia sequenze di caratteri preceduti da una barra inversa (@samp{\}). +Una sequenza di protezione pu@`o essere usata per includere un carattere di +"doppio apice" in una costante stringa. Poich@'e un semplice doppio apice +termina la stringa, va usato @samp{\"} per richiedere che un doppio apice sia +presente all'interno di una stringa. Per esempio: + +@example +$ @kbd{awk 'BEGIN @{ print "Egli le disse \"ciao!\"." @}'} +@print{} Egli le disse "ciao!". +@end example + +Lo stesso carattere di barra inversa @`e un altro carattere che non pu@`o essere +incluso normalmente; occorre scrivere @samp{\\} per inserire una barra +inversa nella stringa o @dfn{regexp}. Quindi, la stringa costituita dai due +caratteri @samp{"} e @samp{\} deve essere scritta come @code{"\"\\"}. + +Altre sequenze di protezione rappresentano caratteri non stampabili +come TAB o il ritorno a capo. Anche se @`e possibile immettere la maggior parte dei +caratteri non stampabili direttamente in una costante stringa o +@dfn{regexp}, essi possono non essere di facile comprensione. + +La seguente lista elenca +tutte le sequenze di protezione usate in @command{awk} e +cosa rappresentano. Se non @`e detto altrimenti, tutte queste sequenze di +protezione valgono sia per costanti stringa che per costanti @dfn{regexp}: + +@table @code +@item \\ +Barra inversa letterale, @samp{\}. + +@c @cindex @command{awk} language, V.4 version +@cindex @code{\} (barra inversa), @code{\a}, sequenza di protezione +@cindex barra inversa (@code{\}), @code{\a}, sequenza di protezione +@item \a +Il carattere ``campanello'', @kbd{Ctrl-g}, codice ASCII 7 (BEL). +(Spesso genera qualche tipo di segnale sonoro udibile.) + +@cindex @code{\} (barra inversa), @code{\b}, sequenza di protezione +@cindex barra inversa (@code{\}), @code{\b}, sequenza di protezione +@item \b +Barra inversa, @kbd{Ctrl-h}, codice ASCII 8 (BS). + +@cindex @code{\} (barra inversa), @code{\f}, sequenza di protezione +@cindex barra inversa (@code{\}), @code{\f}, sequenza di protezione +@item \f +Nuova pagina, @kbd{Ctrl-l}, codice ASCII 12 (FF). + +@cindex @code{\} (barra inversa), @code{\n}, sequenza di protezione +@cindex barra inversa (@code{\}), @code{\n}, sequenza di protezione +@item \n +A capo, @kbd{Ctrl-j}, codice ASCII 10 (LF). + +@cindex @code{\} (barra inversa), @code{\r}, sequenza di protezione +@cindex barra inversa (@code{\}), @code{\r}, sequenza di protezione +@item \r +Ritorno del carrello, @kbd{Ctrl-m}, codice ASCII 13 (CR). + +@cindex @code{\} (barra inversa), @code{\t}, sequenza di protezione +@cindex barra inversa (@code{\}), @code{\t}, sequenza di protezione +@item \t +Tabulazione orizzontale, @kbd{Ctrl-i}, codice ASCII 9 (HT). + +@c @cindex @command{awk} language, V.4 version +@cindex @code{\} (barra inversa), @code{\v}, sequenza di protezione +@cindex barra inversa (@code{\}), @code{\v}, sequenza di protezione +@item \v +Tabulazione verticale, @kbd{Ctrl-k}, codice ASCII 11 (VT). + +@cindex @code{\} (barra inversa), @code{\}@var{nnn}, sequenza di protezione +@cindex barra inversa (@code{\}), @code{\}@var{nnn}, sequenza di protezione +@item \@var{nnn} +Il valore ottale @var{nnn}, dove @var{nnn} pu@`o essere da 1 a 3 cifre ottali, +tra @samp{0} e @samp{7}. Per esempio, il codice per il carattere ASCII ESC +(escape) @`e @samp{\033}. + +@c @cindex @command{awk} language, V.4 version +@c @cindex @command{awk} language, POSIX version +@cindex @code{\} (barra inversa), @code{\x}, sequenza di protezione +@cindex barra inversa (@code{\}), @code{\x}, sequenza di protezione +@cindex comuni, estensioni@comma{} @code{\x}, sequenza di protezione +@cindex estensioni comuni, @code{\x}, sequenza di protezione +@item \x@var{hh}@dots{} +Il valore esadecimale @var{hh}, dove @var{hh} indica una sequenza di cifre +esadecimali (@samp{0}--@samp{9}, e @samp{A}--@samp{F} +o @samp{a}--@samp{f}). Dopo @samp{\x} @`e consentito un massimo di due cifre. +Ogni ulteriore cifra esadecimale @`e considerata come una semplice +lettera o numero. @value{COMMONEXT} +(La sequenza di protezione @samp{\x} non @`e permessa in POSIX awk.) + +@quotation ATTENZIONE +In ISO C, la sequenza di protezione continua fino a raggiungere il primo +carattere che non sia una cifra esadecimale. +In passato, @command{gawk} avrebbe continuato ad aggiungere +cifre esadecimali al valore finch@'e non trovava una cifra non esadecimale +oppure fino a raggiungere la fine della stringa. +Comunque usare pi@`u di due cifre esadecimali produceva risultati indefiniti. +Dalla @value{PVERSION} 4.2, +vengono elaborate solo due cifre. +@end quotation + +@cindex @code{\} (barra inversa), @code{\/}, sequenza di protezione +@cindex barra inversa (@code{\}), @code{\/}, sequenza di protezione +@item \/ +Una barra (necessario solo per costanti @dfn{regexp}). +Questa sequenza si usa per inserire una costante @dfn{regexp} +che contiene una barra +(come @code{/.*:\/home\/[[:alnum:]]+:.*/}; la notazione @samp{[[:alnum:]]} +verr@`a spiegata pi@`u avanti, +@iftex +nella +@end iftex +@ifnottex +in +@end ifnottex +@ref{Espressioni tra parentesi quadre}). +Poich@'e una @dfn{regexp} @`e racchiusa tra +barre, si deve proteggere ogni barra che sia parte dell'espressione, per dire +ad @command{awk} di andare avanti a scandire il resto della @dfn{regexp}. + +@cindex @code{\} (barra inversa), @code{\"}, sequenza di protezione +@cindex barra inversa (@code{\}), @code{\"}, sequenza di protezione +@item \" +Un doppio apice (necessario solo per costanti stringa). +Questa sequenza si usa per inserire in una costante stringa il carattere +doppio apice +(come @code{"Egli le disse \"ciao!\"."}). +Poich@'e la stringa @`e racchiusa tra +doppi apici, si deve proteggere ogni doppio apice che sia parte della stringa +per dire ad @command{awk} di andare avanti a elaborare il resto della stringa. +@end table + +In @command{gawk}, parecchie altre sequenze di due caratteri inizianti con +con una barra inversa hanno un significato speciale nelle @dfn{regexp}. +@ref{Operatori di @dfn{regexp} GNU}. + +In una @dfn{regexp}, una barra inversa che preceda un carattere non presente +nella lista precedente, e non elencato in +@ref{Operatori di @dfn{regexp} GNU}, +significa che il carattere seguente dovrebbe essere preso letteralmente, +anche se normalmente sarebbe un operatore di @dfn{regexp}. Per esempio, +@code{/a\+b/} individua i tre caratteri @samp{a+b}. + +@cindex barra inversa (@code{\}), in sequenze di protezione +@cindex @code{\} (barra inversa), in sequenze di protezione +@cindex portabilit@`a +Per una completa portabilit@`a, non usare una barra inversa prima di qualsiasi +carattere non incluso nella lista precedente, o che non sia un operatore. +@c 11/2014: Moved so as to not stack sidebars +@sidebar Barra inversa prima di un carattere normale +@cindex portabilit@`a, barra inversa in sequenze di protezione +@cindex POSIX @command{awk}, barre inverse in costanti stringa +@cindex barra inversa (@code{\}), in sequenze di protezione, POSIX e +@cindex @code{\} (barra inversa), in sequenze di protezione, POSIX e + +@cindex risoluzione di problemi, barra inversa prima di caratteri non speciali +@cindex problemi, risoluzione di, barra inversa prima di caratteri non speciali +Se si mette una barra inversa in una costante stringa prima di qualcosa che +non sia uno dei caratteri elencati sopra, POSIX @command{awk} di proposito +lascia indefinito il comportamento. Ci sono due possibilit@`a: + +@c @cindex automatic warnings +@c @cindex warnings, automatic +@cindex Brian Kernighan, @command{awk} di +@table @asis +@item Togliere la barra inversa +Questo @`e quel che sia BWK @command{awk} che @command{gawk} fanno. +Per esempio, @code{"a\qc"} equivale a @code{"aqc"}. +(Poich@'e questo @`e un errore che pu@`o capitare o non capitare con la stessa +probabilit@`a, @command{gawk} lo segnala). +Volendo usare come separatore di campo @samp{FS = @w{"[ \t]+\|[ \t]+"}} +ossia delle barre verticali precedute e seguite da almeno uno spazio, +occorre mettere due barre inverse nella stringa: +@samp{FS = @w{"[ \t]+\\|[ \t]+"}}.) +@c I did this! This is why I added the warning. + +@cindex @command{gawk}, sequenze di protezione +@cindex Unix @command{awk}, barre inverse in sequenze di protezione +@cindex @command{mawk}, programma di utilit@`a +@cindex programma di utilit@`a @command{mawk} +@item Tenere la barra inversa cos@`{@dotless{i}} com'@`e. +Alcune altre implementazioni di @command{awk} fanno questo. +In quelle implementazioni, immettere @code{"a\qc"} equivale a immettere +@code{"a\\qc"}. +@end table +@end sidebar +Ricapitolando: + +@itemize @value{BULLET} +@item +Le sequenze di protezione nella lista di cui sopra sono sempre elaborate +per prime, sia per le costanti stringa che per le costanti @dfn{regexp}. Questo +viene fatto quasi subito, non appena @command{awk} legge il programma. + +@item +@command{gawk} elabora sia costanti @dfn{regexp} che @dfn{regexp} dinamiche +(@pxref{Espressioni regolari calcolate}), +per gli operatori speciali elencati in +@ref{Operatori di @dfn{regexp} GNU}. + +@item +Una barra inversa prima di ogni altro carattere richiede di trattare quel +carattere letteralmente. +@end itemize + +@sidebar Sequenze di protezione per metacaratteri +@cindex metacaratteri, sequenze di protezione per + +Supponiamo che si usi una protezione ottale o esadecimale +per rappresentare un metacarattere di @dfn{regexp} +(si veda @ref{Operatori di espressioni regolari}). +@command{awk} considera il carattere come un carattere letterale o +come un operatore di @dfn{regexp}? + +@cindex angolo buio, sequenze di protezione, per metacaratteri +Storicamente, tali caratteri erano considerati letteralmente. +@value{DARKCORNER} +Invece, lo standard POSIX richiede che siano considerati +come metacaratteri veri e propri, e questo @`e ci@`o che @command{gawk} fa. +In modalit@`a compatibile (@pxref{Opzioni}), +@command{gawk} tratta i caratteri scritti come sequenze ottali ed esadecimali +letteramente, quando sono usati in costanti @dfn{regexp}. Quindi, +@code{/a\52b/} @`e equivalente a @code{/a\*b/}. +@end sidebar + +@node Operatori di espressioni regolari +@section Operatori di espressioni regolari +@cindex espressioni regolari, operatori +@cindex metacaratteri in espressioni regolari + +@`E possibile inserire in espressioni regolari dei caratteri speciali, +detti @dfn{operatori di espressioni regolari} o @dfn{metacaratteri}, per +aumentarne il potere e la versatilit@`a. + +Le sequenze di protezione descritte +@ifnotinfo +prima +@end ifnotinfo +in @ref{Sequenze di protezione} +sono valide all'interno di una @dfn{regexp}. Sono precedute da una @samp{\} e +sono riconosciute e convertite nei caratteri reali corrispondenti nella +primissima fase dell'elaborazione delle @dfn{regexp}. + +Ecco una lista dei metacaratteri. Tutti i caratteri che non sono sequenze +di protezione e che non sono elencati qui rappresentano se stessi: + +@c Use @asis so the docbook comes out ok. Sigh. +@table @asis +@cindex barra inversa (@code{\}), operatore @dfn{regexp} +@cindex barra inversa (@code{\}), operatore @dfn{regexp} +@cindex @code{\} (barra inversa), operatore @dfn{regexp} +@item @code{\} +Si usa per togliere il significato speciale a un carattere quando si effettuano +confronti. Per esempio, @samp{\$} +individua il carattere @samp{$}. + +@cindex espressioni regolari, ancore nelle +@cindex Texinfo, inizi di capitolo nei file +@cindex @code{^} (circonflesso), operatore @dfn{regexp} +@cindex circonflesso (@code{^}), operatore @dfn{regexp} +@item @code{^} +Si usa per indicare l'inizio di una stringa. Per esempio, @samp{^@@chapter} +individua @samp{@@chapter} all'inizio di una stringa e si pu@`o usare per +identificare inizi di capitoli in file sorgenti Texinfo. +Il simbolo @samp{^} @`e conosciuto come @dfn{@`ancora}, perch@'e @`ancora la ricerca +solo all'inizio della stringa. + +@`E importante notare che @samp{^} non individua un inizio di riga +(il punto subito dopo un ritorno a capo @samp{\n}) che si trovi all'interno +di una stringa. La condizione non @`e verificata nell'esempio seguente: + +@example +if ("riga1\nRIGA 2" ~ /^R/) @dots{} +@end example + +@cindex @code{$} (dollaro), operatore @dfn{regexp} +@cindex dollaro (@code{$}), operatore @dfn{regexp} +@item @code{$} +Simile a @samp{^}, ma serve a indicare la fine di una stringa. +Per esempio, @samp{p$} +individua un record che termina con la lettera @samp{p}. Il @samp{$} @`e +un'@`ancora e non individua una fine di riga (il punto immediatamente prima +di un carattere di ritorno a capo @samp{\n}) +contenuta in una stringa. +La condizione nell'esempio seguente non @`e verificata: + +@example +if ("riga1\nRIGA 2" ~ /1$/) @dots{} +@end example + +@cindex @code{.} (punto), operatore @dfn{regexp} +@cindex punto (@code{.}), operatore @dfn{regexp} +@item @code{.} (punto) +Individua un qualsiasi carattere, +@emph{incluso} il carattere di ritorno a capo. Per esempio, @samp{.P} +individua ogni carattere in una stringa che sia seguito da una @samp{P}. +Usando la concatenazione, si pu@`o formare un'espressione regolare come +@samp{U.A}, che individua qualsiasi sequenza di tre caratteri che inizia con +@samp{U} e finisce con @samp{A}. + +@cindex POSIX @command{awk}, uso del punto (@code{.}) +In modalit@`a POSIX stretta (@pxref{Opzioni}), +@samp{.} non individua il carattere @sc{nul}, +ossia il carattere con tutti i bit uguali a zero. +In altri contesti, @sc{nul} @`e solo un carattere qualsiasi. Altre versioni +di @command{awk} possono non essere in grado di individuare il carattere +@sc{nul}. + +@cindex @code{[]} (parentesi quadre), operatore @dfn{regexp} +@cindex parentesi quadre (@code{[]}), operatore @dfn{regexp} +@cindex espressioni tra parentesi +@cindex insiemi di caratteri, si veda anche espressioni tra parentesi quadre +@cindex liste di caratteri, si veda espressioni tra parentesi quadre +@cindex classi di caratteri, si veda espressioni tra parentesi quadre +@item @code{[}@dots{}@code{]} +Questa @`e chiamata una @dfn{espressione tra parentesi quadre}.@footnote{In +altri testi, un'espressione tra parentesi quadre potrebbe essere +definita come @dfn{insieme di caratteri}, @dfn{classe di caratteri} o + @dfn{lista di caratteri}.} +Individua @emph{uno} qualsiasi dei caratteri racchiusi tra +parentesi quadre. Per esempio, @samp{[MVX]} individua uno qualsiasi +dei caratteri @samp{M}, @samp{V}, o @samp{X} in una stringa. Una spiegazione +esauriente di quel che si pu@`o mettere all'interno di un'espressione tra +parentesi quadre @`e data in +@ref{Espressioni tra parentesi quadre}. + +@cindex espressioni tra parentesi quadre, complementate +@item @code{[^}@dots{}@code{]} +Questa @`e una @dfn{espressione tra parentesi quadre complementata}. Il primo +carattere dopo la @samp{[} @emph{deve} essere un @samp{^}. Individua +qualsiasi carattere +@emph{tranne} quelli tra parentesi quadre. Per esempio, @samp{[^awk]} +individua qualsiasi carattere che non sia una @samp{a}, @samp{w}, o @samp{k}. + +@cindex @code{|} (barra verticale) +@cindex barra verticale (@code{|}) +@item @code{|} +Questo @`e un @dfn{operatore alternativa} ed @`e usato per specificare delle +alternative. La @samp{|} ha la precedenza pi@`u bassa tra tutti gli operatori +di espressioni regolari. Per esempio, @samp{^P|[aeiouy]} individua tutte le +stringhe corrispondenti a @samp{^P} oppure a @samp{[aeiouy]}. Ci@`o significa +che individua qualsiasi stringa che inizi con @samp{P} o contenga (in +qualsiasi posizione al suo interno) una vocale inglese minuscola. + +L'alternativa si applica alle @dfn{regexp} pi@`u ampie individuabili in ogni +lato. + +@cindex @code{()} (parentesi), operatore @dfn{regexp} +@cindex parentesi (@code{()}), operatore @dfn{regexp} +@item @code{(}@dots{}@code{)} +Le parentesi sono usate per raggruppare, sia nelle espressioni regolari sia +in quelle aritmetiche. Si possono usare per concatenare espressioni regolari +che contengono l'operatore alternativa, @samp{|}. Per esempio, +@samp{@@(samp|code)\@{[^@}]+\@}} individua sia @samp{@@code@{pippo@}} sia +@samp{@@samp@{pluto@}}. +(Queste sono sequenze in linguaggio Texinfo per controllare la formattazione. +Il significato di @samp{+} @`e +spiegato pi@`u avanti in questa lista.) + +@cindex @code{*} (asterisco), operatore @code{*}, come operatore @dfn{regexp} +@cindex asterisco (@code{*}), operatore @code{*}, come operatore @dfn{regexp} +@item @code{*} +Questo simbolo richiede che la precedente espressione regolare sia +ripetuta tante volte quanto serve per trovare una corrispondenza. Per +esempio, @samp{ph*} applica il simbolo +@samp{*} al carattere @samp{h} che lo precede immediatamente e ricerca +corrispondenze costituite da una @samp{p} seguita da un numero qualsiasi di +@samp{h}. Viene individuata anche solo la @samp{p}, se non ci sono +@samp{h}. + +Ci sono due sfumature da capire sul funzionamento di @samp{*}. +Primo, @samp{*} tiene conto solo del singolo componente dell'espressione +regolare che lo precede (p.es., in @samp{ph*} vale solo per @samp{h}). +Per fare s@`{@dotless{i}} che @samp{*} si applichi a una sottoespressione pi@`u estesa, +occorre metterla tra parentesi: +@samp{(ph)*} individua @samp{ph}, @samp{phph}, @samp{phphph} e cos@`{@dotless{i}} via. + +Secondo, @samp{*} trova quante pi@`u ripetizioni siano possibili. Se il testo +da ricercare @`e @samp{phhhhhhhhhhhhhhooey}, @samp{ph*} individua tutte le +@samp{h}. + +@cindex @code{+} (pi@`u), operatore @dfn{regexp} +@cindex pi@`u (@code{+}), operatore @dfn{regexp} +@item @code{+} +Questo simbolo @`e simile a @samp{*}, tranne per il fatto che l'espressione +precedente deve essere trovata almeno una volta. Questo significa che +@samp{wh+y} individuerebbe @samp{why} e @samp{whhy}, ma non @samp{wy}, mentre +@samp{wh*y} li troverebbe tutti e tre. + +@cindex @code{?} (punto interrogativo), operatore @dfn{regexp} +@cindex punto interrogativo (@code{?}), operatore @dfn{regexp} +@item @code{?} +Questo simbolo @`e simile a @samp{*}, tranne per il fatto che l'espressione che +precede pu@`o essere trovata una volta sola oppure non trovata +affatto. Per esempio, @samp{fe?d} +individua @samp{fed} e @samp{fd}, ma nient'altro. + +@cindex espressioni di intervallo, (@dfn{regexp}) +@item @code{@{}@var{n}@code{@}} +@itemx @code{@{}@var{n}@code{,@}} +@itemx @code{@{}@var{n}@code{,}@var{m}@code{@}} +Uno o due numeri tra parentesi graffe rappresentano una +@dfn{espressione di intervallo}. +Se c'@`e un numero tra graffe, la @dfn{regexp} precedente @`e ripetuta +@var{n} volte. +Se ci sono due numeri separati da una virgola, la @dfn{regexp} precedente @`e +ripetuta da @var{n} a @var{m} volte. +Se c'@`e un numero seguito da una virgola, allora la @dfn{regexp} precedente +@`e ripetuta almeno @var{n} volte: + +@table @code +@item wh@{3@}y +Riconosce @samp{whhhy}, ma non @samp{why} o @samp{whhhhy}. + +@item wh@{3,5@}y +Riconosce soltanto @samp{whhhy}, @samp{whhhhy}, o @samp{whhhhhy}. + +@item wh@{2,@}y +Riconosce @samp{whhy}, @samp{whhhy} e cos@`{@dotless{i}} via. +@end table + +@cindex POSIX @command{awk}, espressioni di intervallo in +Le espressioni di intervallo non erano tradizionalmente disponibili in +@command{awk}. Sono state aggiunte come parte dello standard POSIX per +rendere @command{awk} ed @command{egrep} coerenti tra di loro. + +@cindex @command{gawk}, espressioni di intervallo e +In passato, poich@'e vecchi programmi possono usare @samp{@{} e @samp{@}} in +costanti @dfn{regexp}, +@command{gawk} @emph{non} riconosceva espressioni di intervallo +nelle @dfn{regexp}. + +Comunque, a partire dalla @value{PVERSION} 4.0, +@command{gawk} riconosce espressioni di intervallo per default. +Ci@`o accade perch@'e la compatibilit@`a con POSIX @`e ritenuta pi@`u +importante da molti utenti @command{gawk} rispetto alla compatibilit@`a con +dei vecchi programmi. + +Per programmi che usano @samp{@{} e @samp{@}} in costanti @dfn{regexp}, +@`e buona pratica proteggerli sempre con una barra inversa. Allora le +costanti @dfn{regexp} sono valide e si comportano come desiderato, usando +qualsiasi versione di @command{awk}.@footnote{@`E meglio usare due barre inverse +se si sta usando una costante stringa con un operatore @dfn{regexp} o una +funzione.} + +Infine, quando @samp{@{} e @samp{@}} appaiono in costanti @dfn{regexp} +in un modo non interpretabile come espressione di intervallo +(come in @code{/q@{a@}/}), allora sono prese letteralmente. +@end table + +@cindex precedenza, operatore @dfn{regexp} +@cindex espressioni regolari, operatori, precedenza di +Nelle espressioni regolari, gli operatori @samp{*}, @samp{+}, e @samp{?}, +come pure le parentesi graffe @samp{@{} e @samp{@}}, +hanno +la precedenza pi@`u alta, seguiti dalla concatenazione, e infine da @samp{|}. +Come nell'algebra, le parentesi possono cambiare il raggruppamento degli +operatori. +@cindex POSIX @command{awk}, espressioni regolari e +@cindex @command{gawk}, espressioni regolari, precedenza +In POSIX @command{awk} e in @command{gawk}, gli operatori @samp{*}, +@samp{+}, e @samp{?} rappresentano se stessi quando non c'@`e nulla +nella @dfn{regexp} che li precede. Per esempio, @code{/+/} individua un +semplice segno pi@`u. Comunque, molte altre versioni di @command{awk} +trattano una simile notazione come un errore di sintassi. + +Se @command{gawk} @`e in modalit@`a compatibile (@pxref{Opzioni}), le espressioni +di intervallo non si possono usare nelle espressioni regolari. + +@node Espressioni tra parentesi quadre +@section Usare espressioni tra parentesi quadre +@cindex espressioni tra parentesi quadre +@cindex espressioni tra parentesi quadre, espressioni di intervallo +@cindex espressioni di intervallo, (@dfn{regexp}) +@cindex elenchi di caratteri in un'espressione regolare +@cindex caratteri, elenchi di, in un'espressione regolare + +Come detto sopra, un'espressione tra parentesi quadre individua qualsiasi +carattere incluso tra le parentesi quadre aperta e chiusa. + +All'interno di un'espressione tra parentesi quadre, una +@dfn{espressione di intervallo} @`e formata da due caratteri separati da un +trattino. Individua ogni singolo carattere compreso tra i due caratteri, +ordinati secondo l'insieme di caratteri in uso nel sistema. Per esempio, +@samp{[0-9]} @`e equivalente a @samp{[0123456789]}. +(Si veda @ref{Intervalli e localizzazione} per una spiegazione di come +lo standard POSIX e @command{gawk} sono cambiati nel corso degli anni. +La cosa ha un interesse principalmente storico.) + +Con la crescente popolarit@`a dello +@uref{http://www.unicode.org, standard di caratteri Unicode}, +c'@`e un'ulteriore dettaglio da tenere in conto. Le sequenze di +protezione ottali ed esadecimali utilizzabili per inserire +valori all'interno di espressioni tra parentesi quadre +sono considerate contenere solo caratteri +che occupano un unico byte (caratteri il cui valore stia +nell'intervallo 0--256). Per individuare un intervallo di +caratteri in cui i punti di inizio e fine dell'intervello +abbiano valori maggiori di 256, occorre immettere direttamente +le codifiche multi-byte dei caratteri in questione. + +@cindex @code{\} (barra inversa), in espressioni tra parentesi quadre +@cindex barra inversa (@code{\}), in espressioni tra parentesi quadre +@cindex @code{^} (circonflesso), in espressioni tra parentesi quadre +@cindex circonflesso (@code{^}), in espressioni tra parentesi quadre +@cindex @code{-} (meno), in espressioni tra parentesi quadre +@cindex meno (@code{-}), in espressioni tra parentesi quadre +Per includere uno dei caratteri @samp{\}, @samp{]}, @samp{-}, o @samp{^} in +un'espressione tra parentesi quadre, occorre inserire un @samp{\} prima del +carattere stesso. Per esempio: + +@example +[d\]] +@end example + +@noindent +individua sia @samp{d} che @samp{]}. +Inoltre, se si mette una @samp{]} subito dopo la +@samp{[} aperta, la parentesi quadra chiusa @`e considerata come uno dei +caratteri da individuare. + +@cindex POSIX @command{awk}, espressioni tra parentesi quadre e +@cindex espressioni regolari estese (ERE) +@cindex ERE (espressioni regolari estese) +@cindex @command{egrep}, programma di utilit@`a +@cindex programma di utilit@`a @command{egrep} +L'utilizzo di @samp{\} nelle espressioni tra parentesi quadre +@`e compatibile con altre implementazioni di @command{awk} ed @`e anche richiesto +da POSIX. +Le espressioni regolari in @command{awk} sono un insieme pi@`u esteso delle +specificazioni POSIX per le espressioni regolari estese (ERE). +Le ERE POSIX sono basate sulle espressioni regolari accettate dal +tradizionale programma di utilit@`a @command{egrep}. + +@cindex espressioni tra parentesi quadre, classi di caratteri +@cindex POSIX @command{awk}, espressioni tra parentesi quadre e, classi di caratteri +Le @dfn{classi di caratteri} sono una funzionalit@`a introdotta nello standard +POSIX. Una classe di caratteri @`e una particolare notazione per descrivere +liste di caratteri cha hanno un attributo specifico, ma i caratteri +veri e propri possono variare da paese a paese e/o +da insieme di caratteri a insieme di caratteri. Per esempio, la nozione di +cosa sia un carattere alfabetico @`e diversa tra gli Stati Uniti e la Francia. + +Una classe di caratteri @`e valida solo in una @dfn{regexp} @emph{contenuta} +tra le parentesi quadre di un'espressione tra parentesi quadre. Le classi di +caratteri consistono di @samp{[:}, +una parola chiave che segnala la classe, e @samp{:]}. La +@ref{tabella-caratteri-classe} elenca le classi di caratteri definite dallo +standard POSIX. + +@float Tabella,tabella-caratteri-classe +@caption{classi di caratteri POSIX} +@multitable @columnfractions .15 .85 +@headitem Classe @tab Significato +@item @code{[:alnum:]} @tab Caratteri alfanumerici. +@item @code{[:alpha:]} @tab Caratteri alfabetici. +@item @code{[:blank:]} @tab Caratteri spazio e TAB. +@item @code{[:cntrl:]} @tab Caratteri di controllo. +@item @code{[:digit:]} @tab Caratteri numerici. +@item @code{[:graph:]} @tab Caratteri che sono stampabili e visibili. +(Uno @dfn{spazio} @`e stampabile ma non visibile, mentre una @samp{a} @`e l'uno e +l'altro.) +@item @code{[:lower:]} @tab Caratteri alfabetici minuscoli. +@item @code{[:print:]} @tab Caratteri stampabili (caratteri che non sono +caratteri di controllo). +@item @code{[:punct:]} @tab Caratteri di punteggiatura (caratteri che non +sono lettere, cifre, caratteri di controllo, o caratteri di spazio). +@item @code{[:space:]} @tab Caratteri di spazio (come @dfn{spazio}, TAB, e +@dfn{formfeed}, per citarne alcuni). +@item @code{[:upper:]} @tab Caratteri alfabetici maiuscoli. +@item @code{[:xdigit:]} @tab Caratteri che sono cifre esadecimali. +@end multitable +@end float + +Per esempio, prima dello standard POSIX, si doveva scrivere +@code{/[A-Za-z0-9]/} per individuare i +caratteri alfanumerici. Se l'insieme +di caratteri in uso comprendeva altri caratteri alfabetici, l'espressione +non li avrebbe individuati. +Con le classi di caratteri POSIX si pu@`o scrivere +@code{/[[:alnum:]]/} per designare i caratteri alfabetici e numerici +dell'insieme di caratteri in uso. + +@c Thanks to +@c Date: Tue, 01 Jul 2014 07:39:51 +0200 +@c From: Hermann Peifer <peifer@gmx.eu> +Alcuni programmi di utilit@`a che cercano espressioni regolari prevedono +una classe di caratteri, non standard, +@samp{[:ascii:]}; @command{awk} non la prevede. Tuttavia, @`e possibile ottenere +lo stesso risultato utilizzando @samp{[\x00-\x7F]}. Quest'espressione +individua tutti i valori numerici tra zero e 127, che @`e l'intervallo definito +dell'insieme di caratteri ASCII. Usando una lista di caratteri che esclude +(@samp{[^\x00-\x7F]}) si individuano tutti i caratteri mono-byte che non +sono nell'intervallo ASCII. + +@cindex espressioni tra parentesi quadre, elementi di collazione +@cindex espressioni tra parentesi quadre, non-ASCII +@cindex elementi di collazione +In espressioni tra parentesi quadre possono apparire due ulteriori sequenze +speciali. Riguardano insiemi di caratteri non-ASCII, che possono avere +simboli singoli (chiamati @dfn{elementi di collazione}) che sono rappresentati +con pi@`u di un carattere. Possono designare anche parecchi caratteri che sono +equivalenti tra loro ai fini della @dfn{collazione}, o dell'ordinamento. +(Per esempio, in francese, la semplice ``e'' e la sua versione con accento grave ``@`e'' +sono equivalenti). Queste sequenze sono: + +@table @asis +@cindex espressioni tra parentesi quadre, elementi di collazione +@cindex elementi di collazione +@item elementi di collazione +Elementi di collazione multi-byte racchiusi fra +@samp{[.} e @samp{.]}. Per esempio, se @samp{ch} @`e un elemento di collazione, +@samp{[[.ch.]]} @`e una @dfn{regexp} che individua questo elemento di +collazione, mentre @samp{[ch]} @`e una @dfn{regexp} che individua le lettere +@samp{c} o @samp{h}. + +@cindex espressioni tra parentesi quadre, classi di equivalenza +@item classi di equivalenza +Sono nomi, specifici a una particolare localizzazione, per una lista di +caratteri equivalenti tra loro. Il nome @`e racchiuso fra +@samp{[=} e @samp{=]}. +Per esempio, il nome @samp{e} potrebbe essere usato per designare +``e'', ``@^e'', ``@`e'', e ``@'e''. In questo caso, @samp{[[=e=]]} @`e una @dfn{regexp} +che corrisponde a @samp{e}, @samp{@^e}, @samp{@`e} e @samp{@'e}. +@end table + +Queste funzionalit@`a sono molto utili in localizzazioni non inglesi. + +@cindex internazionalizzazione, localizzazione, classi di caratteri +@cindex @command{gawk}, classi di caratteri e +@cindex POSIX @command{awk}, espressioni tra parentesi quadre e, classi di caratteri +@quotation ATTENZIONE +Le funzioni di libreria che @command{gawk} usa per individuare le espressioni +regolari per ora riconoscono solo le classi di caratteri POSIX; +non riconoscono simboli di collazione o classi di equivalenza. +@end quotation +@c maybe one day ... + +In un'espressione tra parentesi quadre, una parentesi aperta (@samp{[}) +che non costituisca l'inizio della specificazione di una classe di +caratteri, di simboli di collazione o di una classe di equivalenza +@`e interpretata letteralmente. Questo vale anche per @samp{.} e @samp{*}. + +@node Pi@`u lungo da sinistra +@section Quanto @`e lungo il testo individuato? + +@cindex espressioni regolari, corrispondenza pi@`u a sinistra +@c @cindex matching, leftmost longest +Si consideri il caso seguente: + +@example +echo aaaabcd | awk '@{ sub(/a+/, "<A>"); print @}' +@end example + +Questo esempio usa la funzione @code{sub()} per modificare il record in input. +(@code{sub()} sostituisce la prima ricorrenza in ogni testo individuato dal +primo argomento con la stringa fornita come secondo argomento; +@pxref{Funzioni per stringhe}.) Qui, la @dfn{regexp} @code{/a+/} richiede +``uno o pi@`u caratteri @samp{a},'' e il testo da sostituire @`e @samp{<A>}. + +L'input contiene quattro caratteri @samp{a}. +Le espressioni regolari @command{awk} (e POSIX) individuano sempre +la sequenza @emph{pi@`u lunga}, partendo da sinistra, di caratteri in input che +corrispondono. Quindi, tutti e quattro i caratteri @samp{a} sono +rimpiazzati con @samp{<A>} in questo esempio: + +@example +$ @kbd{echo aaaabcd | awk '@{ sub(/a+/, "<A>"); print @}'} +@print{} <A>bcd +@end example + +Per semplici test corrisponde/non corrisponde, la cosa ha poca importanza. +Ma se si sta controllando un testo o si fanno sostituzioni usando le funzioni +@code{match()}, @code{sub()}, @code{gsub()} e @code{gensub()}, +@`e invece molto importante. +@ifinfo +@xref{Funzioni per stringhe}, +Per maggiori informazioni su queste funzioni. +@end ifinfo +Tenere in conto questo principio @`e importante anche quando si suddividono +record e campi usando delle @dfn{regexp} (@pxref{Record}, +e anche @pxref{Separatori di campo}). + +@node Espressioni regolari calcolate +@section Usare @dfn{regexp} dinamiche + +@cindex espressioni regolari calcolate +@cindex espressioni regolari dinamiche +@cindex @code{~} (tilde), operatore @code{~} +@cindex tilde (@code{~}), operatore @code{~} +@cindex @code{!} (punto esclamativo), operatore @code{!~} +@cindex punto esclamativo (@code{!}), operatore @code{!~} +@c @cindex operators, @code{~} +@c @cindex operators, @code{!~} +L'espressione a destra di un operatore @samp{~} o @samp{!~} non deve +necessariamente essere una costante @dfn{regexp} (cio@`e, una stringa di +caratteri tra barre). Pu@`o essere una qualsiasi +espressione. L'espressione @`e valutata e convertita in una stringa +se necessario; il contenuto della stringa @`e poi usato come una @dfn{regexp}. +Una @dfn{regexp} calcolata in questo modo @`e detta una @dfn{regexp dinamica} +o una @dfn{regexp calcolata}: + +@example +BEGIN @{ @dfn{regexp}_numerica = "[[:digit:]]+" @} +$0 ~ @dfn{regexp}_numerica @{ print @} +@end example + +@noindent +Questo @dfn{script} imposta @code{regexp_numerica} come una @dfn{regexp} che +descrive una o pi@`u cifre, e poi controlla se un record in input corrisponde a +questa regexp. + +@quotation NOTA +Usando gli operatori @samp{~} e @samp{!~}, si tenga presente che c'@`e +una differenza tra una costante @dfn{regexp} racchiusa tra barre e una +costante stringa racchiusa tra doppi apici. +Se si intende utilizzare una costante stringa, occorre comprendere che +la stringa @`e, in sostanza, scandita @emph{due volte}: la prima volta quando +@command{awk} legge il programma, e la seconda volta quando va a +confrontare la stringa a sinistra dell'operatore con il modello che sta +alla sua destra. Questo vale per ogni espressione (come la +@code{regexp_numerica}, vista nel precedente esempio), non solo per le +costanti stringa. +@end quotation + +@cindex costanti @dfn{regexp}, barre vs.@: doppi apici +@cindex @code{\} (barra inversa), in costanti @dfn{regexp} +@cindex barra inversa (@code{\}), in costanti @dfn{regexp} +@cindex @code{"} (doppio apice), in costanti @dfn{regexp} +@cindex doppio apice (@code{"}), in costanti @dfn{regexp} +Che differenza fa la doppia scansione di una stringa? +La risposta ha a che vedere con le sequenze di protezione e particolarmente +con le barre inverse. Per inserire una barra inversa in un'espressione +regolare all'interno di una stringa, occorre inserire @emph{due} barre +inverse. + +Per esempio, @code{/\*/} @`e una costante @dfn{regexp} per designare un @samp{*} +letterale. +@`E richiesta una sola barra inversa. Per fare lo stesso con una stringa, +occorre immettere @code{"\\*"}. La prima barra inversa protegge la +seconda in modo che la stringa in realt@`a contenga i +due caratteri @samp{\} e @samp{*}. + +@cindex risoluzione di problemi, costanti @dfn{regexp} vs.@: costanti stringa +@cindex problemi, risoluzione di, costanti @dfn{regexp} vs.@: costanti stringa +@cindex costanti @dfn{regexp}, vs.@: costanti stringa +@cindex costanti stringa, vs.@: costanti @dfn{regexp} +Dato che si possono usare sia costanti @dfn{regexp} che costanti stringa per +descrivere espressioni regolari, qual @`e da preferire? La risposta @`e +``costanti @dfn{regexp}'', per molti motivi: + +@itemize @value{BULLET} +@item +Le costanti stringa sono pi@`u complicate da scrivere e pi@`u difficili +da leggere. Usare costanti @dfn{regexp} rende i programmi +meno inclini all'errore. Non comprendere la differenza tra i due tipi di +costanti @`e una fonte frequente di errori. + +@item +@`E pi@`u efficiente usare costanti @dfn{regexp}. @command{awk} pu@`o accorgersi +che @`e stata fornita una @dfn{regexp} e memorizzarla internamente in una forma +che rende la ricerca di corrispondenze pi@`u efficiente. Se si usa una costante +stringa, @command{awk} deve prima convertire la stringa nel suo formato +interno e quindi eseguire la ricerca di corrispondenze. + +@item +Usare costanti @dfn{regexp} @`e la forma migliore; lascia comprendere +chiaramente che si vuole una corrispondenza con una @dfn{regexp}. +@end itemize + +@sidebar Usare @code{\n} in espressioni tra parentesi quadre in @dfn{regexp} dinamiche +@cindex espressioni regolari dinamiche, contenenti dei ritorni a capo +@cindex ritorno a capo, in @dfn{regexp} dinamiche + +Alcune delle prime versioni di @command{awk} non consentono di usare il +carattere di ritorno +a capo all'interno di un'espressione tra parentesi quadre in @dfn{regexp} +dinamiche: + +@example +$ @kbd{awk '$0 ~ "[ \t\n]"'} +@error{} awk: newline in character class [ +@error{} ]... +@error{} source line number 1 +@error{} context is +@error{} $0 ~ "[ >>> \t\n]" <<< +@end example + +@cindex ritorno a capo, in costanti @dfn{regexp} +Ma un ritorno a capo in una costante @dfn{regexp} non d@`a alcun problema: + +@example +$ @kbd{awk '$0 ~ /[ \t\n]/'} +@kbd{ecco una riga di esempio} +@print{} ecco una riga di esempio +@kbd{Ctrl-d} +@end example + +@command{gawk} non ha questo problema, e non dovrebbe accadere spesso +in pratica, ma val la pena di notarlo a futura memoria. +@end sidebar + +@node Operatori di @dfn{regexp} GNU +@section Operatori @dfn{regexp} propri di @command{gawk} + +@c This section adapted (long ago) from the regex-0.12 manual + +@cindex espressioni regolari, operatori, @command{gawk} +@cindex @command{gawk}, espressioni regolari, operatori +@cindex operatori, specifici per GNU +@cindex espressioni regolari, operatori, per parole +@cindex parola, definizione in @dfn{regexp} +Il software GNU che ha a che fare con espressioni regolari comprende alcuni +operatori @dfn{regexp} aggiuntivi. Questi +operatori sono descritti in +@ifnotinfo +questa +@end ifnotinfo +@ifinfo +questo +@end ifinfo +@value{SECTION} e sono specificamente +per @command{gawk}; non sono disponibili in altre implementazioni di +@command{awk}. +La maggior parte degli operatori aggiuntivi riguarda l'identificazione di +parole. Ai nostri fini, una @dfn{parola} @`e una sequenza di uno o pi@`u lettere, +cifre, o trattini bassi (@samp{_}): + +@table @code +@c @cindex operatori, @code{\s} (@command{gawk}) +@cindex barra inversa (@code{\}), @code{\s}, operatore (@command{gawk}) +@cindex @code{\} (barra inversa), @code{\s}, operatore (@command{gawk}) +@item \s +Corrisponde a ogni carattere bianco. +Lo si pu@`o pensare come un'abbreviazione di +@w{@samp{[[:space:]]}}. + +@c @cindex operatori, @code{\S} (@command{gawk}) +@cindex barra inversa (@code{\}), @code{\S}, operatore (@command{gawk}) +@cindex @code{\} (barra inversa), @code{\S}, operatore (@command{gawk}) +@item \S +Corrisponde a ogni carattere che non @`e uno spazio bianco. +Lo si pu@`o pensare come un'abbreviazione di +@w{@samp{[^[:space:]]}}. + +@c @cindex operatori, @code{\w} (@command{gawk}) +@cindex barra inversa (@code{\}), @code{\w}, operatore (@command{gawk}) +@cindex @code{\} (barra inversa), @code{\w}, operatore (@command{gawk}) +@item \w +Corrisponde a ogni carattere che componga una parola; ovvero, corrisponde a +ogni lettera, cifra, o trattino basso. +Lo si pu@`o pensare come un'abbreviazione di +@w{@samp{[[:alnum:]_]}}. + +@c @cindex operatori, @code{\W} (@command{gawk}) +@cindex barra inversa (@code{\}), @code{\W}, operatore (@command{gawk}) +@cindex @code{\} (barra inversa), @code{\W}, operatore (@command{gawk}) +@item \W +Corrisponde a ogni carattere che non @`e parte di una parola. +Lo si pu@`o pensare come un'abbreviazione di +@w{@samp{[^[:alnum:]_]}}. + +@c @cindex operatori, @code{\<} (@command{gawk}) +@cindex barra inversa (@code{\}), @code{\<}, operatore (@command{gawk}) +@cindex @code{\} (barra inversa), @code{\<}, operatore (@command{gawk}) +@item \< +Individua la stringa nulla all'inizio di una parola. +Per esempio, @code{/\<via/} individua @samp{via} ma non +@samp{funivia}. + +@c @cindex operatori, @code{\>} (@command{gawk}) +@cindex barra inversa (@code{\}), @code{\>}, operatore (@command{gawk}) +@cindex @code{\} (barra inversa), @code{\>}, operatore (@command{gawk}) +@item \> +Individua la stringa nulla alla fine di una parola. +Per esempio, @code{/via\>/} individua @samp{via} ma non @samp{viadotto}. + +@c @cindex operatori, @code{\y} (@command{gawk}) +@cindex barra inversa (@code{\}), @code{\y}, operatore (@command{gawk}) +@cindex @code{\} (barra inversa), @code{\y}, operatore (@command{gawk}) +@cindex limite-di-parola, individuare il +@item \y +Individua la stringa nulla o alla fine o all'inizio di una parola. +(cio@`e, il limite di una parola - @dfn{boundar@strong{y}} in inglese). +Per esempio, @samp{\yradar?\y} +individua sia @samp{rada} che @samp{radar}, come parole separate. + +@c @cindex operatori, @code{\B} (@command{gawk}) +@cindex barra inversa (@code{\}), @code{\B}, operatore (@command{gawk}) +@cindex @code{\} (barra inversa), @code{\B}, operatore (@command{gawk}) +@item \B +Individua la stringa nulla che ricorre all'interno di una parola. +Per esempio, +@code{/\Bora\B/} individua @samp{Colorado}, ma non individua @samp{che ora @`e}. +@samp{\B} @`e essenzialmente l'opposto di @samp{\y}. +@end table + +@cindex buffer, operatori per +@cindex espressioni regolari, operatori, per buffer +@cindex operatori, ricerca in stringhe, per buffer +Ci sono due altri operatori che operano sui buffer. In Emacs un +@dfn{buffer} @`e, naturalmente, un buffer di Emacs. In altri programmi GNU, +fra cui @command{gawk}, le routine di libreria delle @dfn{regexp} considerano +come buffer l'intera stringa su cui effettuare il confronto. +Gli operatori sono: + +@table @code +@item \` +@c @cindex operatori, @code{\`} (@command{gawk}) +@cindex barra inversa (@code{\}), @code{\`}, operatore (@command{gawk}) +@cindex @code{\} (barra inversa), @code{\`}, operatore (@command{gawk}) +Individua la stringa nulla che occorre all'inizio di un buffer +(di una stringa) + +@c @cindex operatori, @code{\'} (@command{gawk}) +@cindex barra inversa (@code{\}), @code{\'}, operatore (@command{gawk}) +@cindex @code{\} (barra inversa), @code{\'}, operatore (@command{gawk}) +@item \' +Individua la stringa nulla che occorre alla fine di un buffer +(di una stringa) +@end table + +@cindex @code{^} (circonflesso), operatore @dfn{regexp} +@cindex circonflesso (@code{^}), operatore @dfn{regexp} +@cindex @code{?} (punto interrogativo), operatore @dfn{regexp} +@cindex punto interrogativo (@code{?}), operatore @dfn{regexp} +Poich@'e @samp{^} e @samp{$} si riferiscono sempre all'inizio e alla +fine di stringhe, questi operatori non aggiungono nuove funzionalit@`a +ad @command{awk}. Sono inclusi per compatibilit@`a con altro +software GNU. + +@cindex @command{gawk}, operatore limite-di-parola +@cindex limite-di-parola, operatore (@command{gawk}) +@cindex operatori, limite-di-parola (@command{gawk}) +In altro software GNU, l'operatore di limite-di-parola @`e @samp{\b}. Questo, +comunque, @`e in conflitto con la definizione, nel linguaggio @command{awk}, +di @samp{\b} come +backspace, quindi @command{gawk} usa una lettera differente. +Un metodo alternativo sarebbe stato di richiedere due barre inverse negli +operatori GNU, ma questo @`e stato ritenuto troppo arzigogolato. Il metodo +corrente di usare @samp{\y} al posto del @samp{\b} di GNU sembra essere +il male minore. + +@cindex espressioni regolari, @command{gawk}, opzioni sulla riga di comando +@cindex @command{gawk}, opzioni sulla riga di comando, ed espressioni regolari +Le varie opzioni sulla riga di comando +(@pxref{Opzioni}) +controllano come @command{gawk} interpreta i caratteri nelle @dfn{regexp}: + +@table @asis +@item Nessuna opzione +Per default, @command{gawk} fornisce tutte le funzionalit@`a delle +regexp POSIX e gli +operatori @dfn{regexp} GNU +@ifnotinfo +predecentemente descritti. +@end ifnotinfo +@ifnottex +@ifnotdocbook +Sono descritti +in @ref{Operatori di espressioni regolari}. +@end ifnotdocbook +@end ifnottex + +@item @code{--posix} +Sono ammesse solo le @dfn{regexp} POSIX; gli operatori GNU non sono +speciali (p.es., @samp{\w} individua una semplice lettera @samp{w}). +Le espressioni di intervallo sono ammesse. + +@cindex Brian Kernighan, @command{awk} di +@item @code{--traditional} +Le @dfn{regexp} Unix tradizionali di @command{awk} sono ammesse. Gli +operatori GNU non sono speciali, e le espressioni +di intervallo non sono ammesse. +Le classi di caratteri POSIX (@samp{[[:alnum:]]}, etc.) sono ammesse, +poich@'e BWK @command{awk} le prevede. +I caratteri descritti usando sequenze di protezione ottali ed esadecimali sono +trattati letteralmente, anche se rappresentano metacaratteri di @dfn{regexp}. + +@item @code{--re-interval} +Sono consentite espressioni di intervallo in @dfn{regexp}, +se @option{--traditional} @`e stata specificata. +Altrimenti, le espressioni di intervallo sono disponibili per default. +@end table + +@node Maiuscolo-Minuscolo +@section Fare confronti ignorando maiuscolo/minuscolo + +@cindex espressioni regolari, maiuscolo/minuscolo +@cindex @dfn{regexp}, maiuscolo/minuscolo +@cindex maiuscolo/minuscolo e @dfn{regexp} +Il tipo di carattere (maiuscolo/minuscolo) @`e normalmente rilevante nelle +espressioni regolari, sia nella ricerca di +caratteri normali (cio@`e, non metacaratteri), sia all'interno di espressioni +fra parentesi. Quindi, una @samp{w} in un'espressione regolare individua +solo una @samp{w} e non la corrispondente maiuscola @samp{W}. + +Il modo pi@`u semplice per richiedere una ricerca non sensibile al +maiuscolo/minuscolo @`e di usare un'espressione tra parentesi quadre, per +esempio @samp{[Ww]}. Comunque, questo pu@`o essere pesante se si usa spesso, +e pu@`o rendere le espressioni regolari di difficile lettura. +Ci sono due alternative che potrebbero essere preferibili. + +Un modo per fare un confronto non sensibile a maiuscolo/minuscolo in un +particolare punto del programma +@`e di convertire i dati in un solo tipo (o minuscole o maiuscole), +usando le funzioni di stringa +predefinite @code{tolower()} o @code{toupper()} (che non +abbiamo ancora introdotto; +@pxref{Funzioni per stringhe}). +Per esempio: + +@example +tolower($1) ~ /foo/ @{ @dots{} @} +@end example + +@noindent +converte il primo campo in minuscole, prima di fare un confronto. +Questo funziona in ogni @command{awk} conforme allo standard POSIX. + +@cindex @command{gawk}, espressioni regolari, differenza maiuscolo/minuscolo +@cindex distinzione maiuscolo/minuscolo, @command{gawk} +@cindex differenze tra @command{awk} e @command{gawk}, espressioni regolari +@cindex @code{~} (tilde), operatore @code{~} +@cindex tilde (@code{~}), operatore @code{~} +@cindex @code{!} (punto esclamativo), operatore @code{!~} +@cindex punto esclamativo (@code{!}), operatore @code{!~} +@cindex @code{IGNORECASE}, variabile, con operatori @code{~} e @code{!~} +@cindex @command{gawk}, variabile @code{IGNORECASE} in +@c @cindex variables, @code{IGNORECASE} +Un altro metodo, proprio di @command{gawk}, @`e di impostare la variabile +@code{IGNORECASE} a un valore diverso da zero (@pxref{Variabili predefinite}). +Quando @code{IGNORECASE} @`e diverso da zero, @emph{tutte} le operazioni con +regexp e stringhe ignorano la distinzione maiuscolo/minuscolo. + +Il cambio del valore di @code{IGNORECASE} controlla dinamicamente la +sensibilit@`a a maiuscolo/minuscolo del programma quando @`e in esecuzione. +Il tipo di carattere (maiuscolo/minuscolo) @`e rilevante per default, +poich@'e @code{IGNORECASE} (come la maggior parte delle variabili) @`e +inizializzata a zero: + +@example +x = "aB" +if (x ~ /ab/) @dots{} # questo test non risulter@`a verificato + +IGNORECASE = 1 +if (x ~ /ab/) @dots{} # adesso sar@`a verificato +@end example + +In generale, non @`e possibile usare @code{IGNORECASE} per rendere certe regole +non sensibili a maiuscolo/minuscolo e altre regole invece s@`{@dotless{i}}, perch@'e non c'@`e +una maniera diretta per impostare +@code{IGNORECASE} solo per l'espressione di +una particolare regola.@footnote{Programmatori esperti in C e C++ noteranno +che questo @`e possible, usando qualcosa come +@samp{IGNORECASE = 1 && /foObAr/ @{ @dots{} @}} +e +@samp{IGNORECASE = 0 || /foobar/ @{ @dots{} @}}. +Comunque, questo @`e un po' tortuoso e non @`e raccomandato.} +Per fare questo, si usino espressioni tra parentesi quadre oppure +@code{tolower()}. Comunque, una cosa che si pu@`o fare con @code{IGNORECASE} +soltanto @`e di utilizzare o di ignorare la sensibilit@`a a maiuscolo/minuscolo +per tutte le regole contemporaneamente. + +@code{IGNORECASE} @`e impostabile dalla riga di comando o in una regola +@code{BEGIN} (@pxref{Altri argomenti}; e +@pxref{Usare BEGIN/END}). +Impostare @code{IGNORECASE} dalla riga di comando @`e un modo per rendere +un programma insensibile a maiuscolo/minuscolo senza doverlo modificare. + +@c @cindex ISO 8859-1 +@c @cindex ISO Latin-1 +In localizzazioni multibyte, +le equivalenze tra caratteri maiuscoli +e minuscoli sono controllate usando i valori in formato esteso +dell'insieme di caratteri della localizzazione. +Per il resto, i caratteri sono controllati usando l'insieme di caratteri +ISO-8859-1 (ISO Latin-1). +Questo insieme di caratteri @`e un'estensione del tradizionale insieme con 128 +caratteri ASCII, che include anche molti caratteri adatti +per le lingue europee.@footnote{Se questo sembra oscuro, +non c'@`e ragione di preoccuparsi; significa solo che @command{gawk} fa +la cosa giusta.} + +Il valore di @code{IGNORECASE} non ha effetto se @command{gawk} @`e in +modalit@`a compatibile (@pxref{Opzioni}). +Il tipo di carattere (maiuscolo o minuscolo) @`e sempre rilevante in modalit@`a +compatibile. + +@node Sommario espressioni regolari +@section Sommario + +@itemize @value{BULLET} +@item +Le espressioni regolari descrivono insiemi di stringhe da confrontare. +In @command{awk}, le costanti @dfn{regexp} sono scritte racchiuse +fra barre: @code{/}@dots{}@code{/}. + +@item +Le costanti @dfn{regexp} possono essere usate da sole in modelli di ricerca e +in espressioni condizionali, o come parte di espressioni di ricerca +usando gli operatori @samp{~} e @samp{!~}. + +@item +Le sequenze di protezione consentono di rappresentare caratteri non stampabili +e consentono anche di rappresentare metacaratteri @dfn{regexp} come caratteri +letterali per i quali cercare corrispondenze. + +@item +Gli operatori @dfn{regexp} consentono raggruppamento, alternativa e +ripetizione. + +@item +Le espressioni tra parentesi quadre sono delle notazioni abbreviate per +specificare insiemi di caratteri che possono avere corrispondenze in un +punto particolare di una @dfn{regexp}. +All'interno di espressioni tra parentesi quadre, le classi di caratteri POSIX +consentono di specificare certi gruppi di caratteri in maniera indipendente +dalla localizzazione. + +@item +Le espressioni regolari individuano il testo pi@`u lungo possibile, a partire +da sinistra nella stringa in esame. Questo ha importanza nei casi in cui +serve conoscere la lunghezza della corrispondenza, come nella sostituzione di +testo e quando il separatore di record sia una @dfn{regexp}. + +@item +Espressioni di ricerca possono usare @dfn{regexp} dinamiche, ossia, i valori +delle stringhe sono considerato come espressioni regolari. + +@item +La variabile @command{gawk} @code{IGNORECASE} consente di controllare la +differenza maiuscolo/minuscolo nel confronto mediante @dfn{regexp}. In altre +versioni di @command{awk}, vanno usate invece le funzioni @code{tolower()} o +@code{toupper()}. + +@end itemize + +@node Leggere file +@chapter Leggere file in input + +@cindex leggere file in input +@cindex file in input, leggere +@cindex file in input +@cindex @code{FILENAME}, variabile +@cindex variabile @code{FILENAME} +Nel tipico programma @command{awk}, +@command{awk} legge tutto l'input sia dallo standard input +(per default @`e la tastiera, ma spesso @`e una @dfn{pipe} da un altro comando) +o da file i cui nomi vengono specificati sulla riga di comando di +@command{awk}. Se si specificano file in input, @command{awk} li legge +nell'ordine, elaborando tutti i dati di uno prima di passare al successivo. +Il nome del file in input corrente si trova nella variabile predefinita +@code{FILENAME} +(@pxref{Variabili predefinite}). + +@cindex record +@cindex campi +L'input @`e letto in unit@`a chiamate @dfn{record}, e viene elaborato, secondo le +regole del programma, un record alla volta. +Per default, ogni record @`e una riga. Ogni +record @`e suddiviso automaticamente in "pezzi" chiamati @dfn{campi}. +Questo rende pi@`u pratico far lavorare i programmi sulle parti di un record. + +@cindex @code{getline}, comando +In rare occasioni, si potrebbe aver bisogno di usare il comando +@code{getline}. Il comando @code{getline} @`e utile sia perch@'e pu@`o procurare +un input esplicito da un numero indeterminato di file, sia perch@'e non vanno +specificati sulla riga di comando di @command{awk} i nomi dei file usati con +getline (@pxref{Getline}). + +@menu +* Record:: Controllare come i dati sono suddivisi + in record. +* Campi:: Un'introduzione ai campi. +* Campi non costanti:: Numeri di campo variabili. +* Cambiare i campi:: Cambiare il contenuto di un campo. +* Separatori di campo:: I separatori di campo, e come + cambiarli. +* Dimensione costante:: Leggere campi di larghezza costante. +* Separazione in base al contenuto:: Definire campi dal loro contenuto. +* Righe multiple:: Leggere record che sono su pi@`u righe. +* Getline:: Leggere file sotto il controllo del + programma, usando la funzione + @code{getline}. +* Timeout in lettura:: Leggere input entro un tempo limite. +* Proseguire dopo errore in input:: Elaborare ulteriore input dopo certi + errori di I/O. +* Directory su riga di comando:: Cosa succede mettendo una directory + sulla riga di comando. +* Sommario di Input:: Sommario di Input. +* Esercizi su Input:: Esercizi. +@end menu + +@node Record +@section Controllare come i dati sono suddivisi in record + +@cindex input, suddividere in record +@cindex record, suddividere l'input in +@cindex @code{NR}, variabile +@cindex @code{FNR}, variabile +@command{awk} suddivide l'input per il programma in record e campi. +Tiene traccia del numero di record gi@`a letti dal +file in input corrente. Questo valore @`e memorizzato in una variabile +predefinita chiamata @code{FNR} che @`e reimpostata a zero ogni volta che si +inizia un nuovo file. Un'altra variabile predefinita, @code{NR}, registra il +numero totale di record in input gi@`a letti da tutti i @value{DF}. +Il suo valore iniziale @`e zero ma non viene mai reimpostata a zero +automaticamente. + +@menu +* awk divisione record:: Come @command{awk} standard divide i record. +* gawk divisione record:: Come @command{gawk} divide i record. +@end menu + +@node awk divisione record +@subsection Come @command{awk} standard divide i record. + +@cindex separatori di record +@cindex record, separatori di +I record sono separati da un carattere chiamato @dfn{separatore di record}. +Per default, il separatore di record @`e il carattere di ritorno a capo. +Questo @`e il motivo per cui i record sono, per default, righe singole. +Per usare un diverso carattere come separatore di record +basta assegnare quel carattere alla variabile predefinita @code{RS}. + +@cindex ritorno a capo, come separatore di record +@cindex a capo, come separatore di record +@cindex @code{RS}, variabile +Come per ogni altra variabile, +il valore di @code{RS} pu@`o essere cambiato nel programma @command{awk} +con l'operatore di assegnamento, @samp{=} +(@pxref{Operatori di assegnamento}). +Il nuovo separatore di record dovrebbe essere racchiuso tra doppi apici, +per indicare una costante di stringa. Spesso il momento giusto per far questo +@`e all'inizio dell'esecuzione, prima che sia elaborato qualsiasi input, +in modo che il primo record sia letto col separatore appropriato. +Per far ci@`o, si usa il criterio speciale @code{BEGIN} +(@pxref{BEGIN/END}). +Per esempio: + +@example +awk 'BEGIN @{ RS = "u" @} + @{ print $0 @}' mail-list +@end example + +@noindent +cambia il valore di @code{RS} in @samp{u}, prima di leggere qualsiasi input. +Il nuovo valore @`e una stringa il cui primo carattere @`e la lettera ``u''; come +risultato, i record sono separati dalla lettera ``u''. Poi viene letto il +file in input, e la seconda regola nel programma @command{awk} (l'azione +eseguita se non si specifica un criterio) +stampa ogni record. Poich@'e ogni istruzione @code{print} aggiunge +un ritorno a capo alla fine del suo output, questo programma +@command{awk} copia l'input con ogni @samp{u} trasformato in un ritorno +a capo. Qui vediamo il risultato dell'esecuzione del programma sul file +@file{mail-list}: + +@example +$ @kbd{awk 'BEGIN @{ RS = "u" @}} +> @kbd{@{ print $0 @}' mail-list} +@print{} Amelia 555-5553 amelia.zodiac +@print{} sq +@print{} e@@gmail.com F +@print{} Anthony 555-3412 anthony.assert +@print{} ro@@hotmail.com A +@print{} Becky 555-7685 becky.algebrar +@print{} m@@gmail.com A +@print{} Bill 555-1675 bill.drowning@@hotmail.com A +@print{} Broderick 555-0542 broderick.aliq +@print{} otiens@@yahoo.com R +@print{} Camilla 555-2912 camilla.inf +@print{} sar +@print{} m@@skynet.be R +@print{} Fabi +@print{} s 555-1234 fabi +@print{} s. +@print{} ndevicesim +@print{} s@@ +@print{} cb.ed +@print{} F +@print{} J +@print{} lie 555-6699 j +@print{} lie.perscr +@print{} tabor@@skeeve.com F +@print{} Martin 555-6480 martin.codicib +@print{} s@@hotmail.com A +@print{} Sam +@print{} el 555-3430 sam +@print{} el.lanceolis@@sh +@print{} .ed +@print{} A +@print{} Jean-Pa +@print{} l 555-2127 jeanpa +@print{} l.campanor +@print{} m@@ny +@print{} .ed +@print{} R +@print{} +@end example + +@noindent +Si noti che la voce relativa al nome @samp{Bill} non @`e divisa. +Nel @value{DF} originale +(@pxref{File dati di esempio}), +la riga appare in questo modo: + +@example +Bill 555-1675 bill.drowning@@hotmail.com A +@end example + +@noindent +Essa non contiene nessuna @samp{u}, per cui non c'@`e alcun motivo di dividere +il record, diversamente dalle altre, che hanno una o pi@`u ricorrenze della +@samp{u}. Infatti, questo record @`e trattato come parte del record precedente; +il ritorno a capo che li separa nell'output @`e l'originale ritorno a capo nel +@value{DF}, non quella aggiunta da @command{awk} quando ha stampato il record! + +@cindex separatori di record, cambiare i +@cindex record, separatori di +Un altro modo per cambiare il separatore di record @`e sulla riga di comando, +usando la funzionalit@`a dell'assegnamento di variabile +(@pxref{Altri argomenti}): + +@example +awk '@{ print $0 @}' RS="u" mail-list +@end example + +@noindent +Questo imposta @code{RS} a @samp{u} prima di elaborare @file{mail-list}. + +Usando un carattere alfabetico come @samp{u} come separatore di record +@`e molto probabile che si ottengano risultati strani. +Usando un carattere insolito come @samp{/} @`e pi@`u probabile +che si ottenga un comportamento corretto nella maggioranza dei casi, ma non +c'@`e nessuna garanzia. La morale @`e: conosci i tuoi dati! + +Quando si usano caratteri normali come separatore di record, +c'@`e un caso insolito che capita quando @command{gawk} +@`e reso completamente conforme a POSIX (@pxref{Opzioni}). +In quel caso, la seguente (estrema) @dfn{pipeline} stampa un sorprendente +@samp{1}: + +@example +$ echo | gawk --posix 'BEGIN @{ RS = "a" @} ; @{ print NF @}' +@print{} 1 +@end example + +C'@`e un solo campo, consistente in un ritorno a capo. Il valore della +variabile predefinita @code{NF} @`e il numero di campi nel record corrente. +(Normalmente @command{gawk} tratta il ritorno a capo come uno spazio +vuoto, stampando @samp{0} come risultato. Anche molte altre versioni di +@command{awk} agiscono in questo modo.) + +@cindex angolo buio, file in input +Il raggiungimento della fine di un file in input fa terminare il record di +input corrente, anche se l'ultimo carattere nel file non @`e il carattere in +@code{RS}. @value{DARKCORNER} + +@cindex stringhe vuote +@cindex stringhe nulle +@c @cindex strings, empty, see null strings +La stringa nulla @code{""} (una stringa che non contiene alcun carattere) +ha un significato particolare come +valore di @code{RS}. Significa che i record sono separati +soltanto da una o pi@`u righe vuote. +@xref{Righe multiple} per maggiori dettagli. + +Se si cambia il valore di @code{RS} nel mezzo di un'esecuzione di +@command{awk}, il nuovo valore @`e usato per delimitare i record successivi, ma +non riguarda il record in corso di elaborazione e neppure quelli gi@`a +elaborati. + +@cindex @command{gawk}, variabile @code{RT} in +@cindex @code{RT}, variabile +@cindex record, fine dei +@cindex differenze tra @command{awk} e @command{gawk}, separatori di record +@cindex espressioni regolari, come separatori di record +@cindex record, separatori di, espressioni regolari come +@cindex separatori di record, espressioni regolari come +Dopo che @`e stata determinata la fine di un record, @command{gawk} +imposta la variabile @code{RT} al testo nell'input che corrisponde a +@code{RS}. + +@node gawk divisione record +@subsection Divisione dei record con @command{gawk} + +@cindex estensioni comuni, @code{RS} come espressione regolare +@cindex comuni, estensioni@comma{} @code{RS} come espressione regolare +Quando si usa @command{gawk}, +il valore di @code{RS} non @`e limitato a una stringa costituita da un solo +carattere, ma pu@`o essere qualsiasi espressione regolare +@iftex +(@pxrefil{Espressioni regolari}). @value{COMMONEXT} +@end iftex +@ifnottex +(@pxref{Espressioni regolari}). @value{COMMONEXT} +@end ifnottex +In generale, ogni record termina alla stringa pi@`u vicina che corrisponde +all'espressione regolare; il record successivo inizia alla fine della stringa +che corrisponde. Questa regola generale @`e in realt@`a applicata anche nel caso +normale, in cui @code{RS} contiene solo un ritorno a capo: un record +termina all'inizio della prossima stringa che corrisponde (il prossimo +ritorno a capo nell'input), e il record seguente inizia subito dopo la +fine di questa stringa (al primo carattere della riga seguente). +Il ritorno a capo, poich@'e corrisponde a @code{RS}, non appartiene a +nessuno dei due record. + +Quando @code{RS} @`e un singolo carattere, @code{RT} +contiene lo stesso singolo carattere. Peraltro, quando @code{RS} @`e +un'espressione regolare, @code{RT} contiene l'effettivo testo in input +corrispondente all'espressione regolare. + +Se il file in input termina senza che vi sia un testo che corrisponda a +@code{RS}, @command{gawk} imposta @code{RT} alla stringa nulla. + +Il seguente esempio illustra entrambe queste caratteristiche. +In quest'esempio @code{RS} @`e impostato a un'espressione regolare che +cerca sia un ritorno a capo che una serie di una o pi@`u lettere +maiuscole con uno spazio vuoto opzionale iniziale e/o finale: + +@example +$ @kbd{echo record 1 AAAA record 2 BBBB record 3 |} +> @kbd{gawk 'BEGIN @{ RS = "\n|( *[[:upper:]]+ *)" @}} +> @kbd{@{ print "Record =", $0,"e RT = [" RT "]" @}'} +@print{} Record = record 1 e RT = [ AAAA ] +@print{} Record = record 2 e RT = [ BBBB ] +@print{} Record = record 3 e RT = [ +@print{} ] +@end example + +@noindent +Le parentesi quadre racchiudono il contenuto di @code{RT}, rendendo visibile +lo spazio vuoto iniziale e quello finale. L'ultimo valore di +@code{RT} @`e un ritorno a capo. +@xref{Programma sed semplice} per un esempio pi@`u utile +su @code{RS} come espressione regolare e su @code{RT}. + +Se si imposta @code{RS} a un'espressione regolare che consente del testo +finale opzionale, come @samp{RS = "abc(XYZ)?"} @`e possibile, per via di +limitazioni dell'implementazione, che @command{gawk} possa trovare la parte +iniziale dell'espressione regolare, ma non la parte finale, in modo +particolare se il testo di input che potrebbe avere una corrispondenza con la +parte finale @`e piuttosto lungo. @command{gawk} cerca di evitare questo +problema, ma al momento non ci sono garanzie che questo funzioni sempre. + +@quotation NOTA +Si ricordi che in @command{awk}, i metacaratteri di ancoraggio @samp{^} e +@samp{$} trovano l'inizio e la fine di una @emph{stringa}, e non l'inizio e la +fine di una @emph{riga}. Come risultato, qualcosa come +@samp{RS = "^[[:upper:]]"} pu@`o solo corrispondere all'inizio di un file. +Questo perch@'e @command{gawk} vede il file in input come un'unica lunga stringa +in cui possono essere presenti dei caratteri di ritorno a capo. +@`E meglio perci@`o evitare metacaratteri di ancoraggio nel valore di @code{RS}. +@end quotation + +@cindex differenze tra @command{awk} e @command{gawk}, variabili @code{RS}/@code{RT} +L'uso di @code{RS} come espressione regolare e la variabile @code{RT} sono +estensioni @command{gawk}; non sono disponibili in +modalit@`a compatibile +(@pxref{Opzioni}). +In modalit@`a compatibile, solo il primo carattere del valore di +@code{RS} determina la fine del record. + +@sidebar @code{RS = "\0"} non @`e portabile +@cindex portabilit@`a, file di dati come un unico record +Ci sono casi in cui capita di dover trattare un intero @value{DF} come +un record unico. L'unico modo di far questo @`e quello di dare a @code{RS} +un valore che non ricorre nel file in input. Ci@`o @`e difficile da fare in modo +generale, cos@`{@dotless{i}} che un programma possa +funzionare con file in input arbitrari. + +Si potrebbe pensare che per i file di testo il carattere @sc{NUL}, che +consiste di un carattere con tutti i bit uguali a zero, sia un buon valore da +usare per @code{RS} in questo caso: + +@example +BEGIN @{ RS = "\0" @} # l'intero file diventa un record? +@end example + +@cindex differenze tra @command{awk} e @command{gawk}, stringhe, memorizzazione +@command{gawk} di fatto lo accetta, e usa il carattere @sc{NUL} +come separatore di record. +Questo funziona per certi file speciali, come @file{/proc/environ} su sistemi +GNU/Linux, dove il carattere @sc{NUL} @`e di fatto un separatore di record.. +Comunque, quest'uso @emph{non} @`e portabile sulla maggior parte delle +implementazioni di @command{awk}. + +@cindex angolo buio, stringhe, memorizzazione +Quasi tutte le altre implementazioni di @command{awk} @footnote{Almeno quelle +che ci sono note.} memorizzano internamente le stringhe come stringhe +in stile C. Le stringhe in stile C usano il carattere @sc{NUL} come +terminatore di stringa. In effetti, questo significa che +@samp{RS = "\0"} @`e lo stesso di @samp{RS = ""}. +@value{DARKCORNER} + +Capita che recenti versioni di @command{mawk} possano usare i carattere +@sc{NUL} come separatore di record. Comunque questo @`e un caso particolare: +@command{mawk} non consente di includere caratteri @sc{NUL} nelle stringhe. +(Ci@`o potrebbe cambiare in una versione futura di @command{mawk}.) + +@cindex record, trattare un file come un solo +@cindex trattare un file, come un solo record +@xref{Funzione readfile} per un modo interessante di leggere +file interi. Se si usa @command{gawk}, si veda +@ref{Esempio di estensione Readfile} per un'altra opzione. +@end sidebar + +@node Campi +@section Un'introduzione ai campi + +@cindex esaminare i campi +@cindex campi +@cindex accesso ai campi +@cindex campi, esame dei +Quando @command{awk} legge un record in input, il record @`e +automaticamente @dfn{analizzato} o separato da @command{awk} in "pezzi" +chiamati @dfn{campi}. Per default, i campi sono separati da +@dfn{spazi vuoti}, come le parole in una riga stampata. +Uno spazio vuoto in @command{awk} @`e qualsiasi stringa composta da uno o pi@`u +spazi, segni di tabulazione o ritorni a capo; +altri caratteri, come interruzione di pagina, tabulazione verticale, etc., che +sono considerati spazi vuoti in altri linguaggi, @emph{non} sono considerati +tali da @command{awk}. + +Lo scopo dei campi @`e quello di rendere pi@`u conveniente per l'utente far +riferimento a questi frammenti dei record. Non @`e necessario usarli---si pu@`o +operare sull'intero record, se si vuole---ma i campi sono ci@`o che rende +cos@`{@dotless{i}} potenti dei semplici programmi @command{awk}. + +@cindex operatore di campo @code{$} +@cindex @code{$} (dollaro), operatore di campo @code{$} +@cindex dollaro (@code{$}), operatore di campo @code{$} +@cindex operatore di campo, dollaro come +Si usa il simbolo del dollaro (@samp{$}) +per far riferimento a un campo in un programma @command{awk}, +seguito dal numero del campo desiderato. Quindi, @code{$1} +si riferisce al primo campo, @code{$2} al secondo, e cos@`{@dotless{i}} via. +(Diversamente che nelle shell Unix, i numeri di campo non sono limitati a una +sola cifra; @code{$127} @`e il centoventisettesimo campo nel record.) +Per esempio, supponiamo che la seguente sia una riga in input: + +@example +Questo pare essere un esempio proprio carino. +@end example + +@noindent +Qui il primo campo, o @code{$1}, @`e @samp{Questo}, il secondo campo, o +@code{$2}, @`e @samp{pare}, e via dicendo. Si noti che l'ultimo campo, +@code{$7}, @`e @samp{carino.}. Poich@'e non ci sono spazi tra la +@samp{o} e il @samp{.}, il punto @`e considerato parte del settimo +campo. + +@cindex @code{NF}, variabile +@cindex campi, numero dei +@code{NF} @`e una variabile predefinita il cui valore @`e il numero di campi nel +record corrente. @command{awk} aggiorna automaticamente il valore di +@code{NF} ogni volta che legge un record. Indipendentemente da quanti campi +ci possano essere, l'ultimo campo in un record pu@`o essere rappresentato da +@code{$NF}. Cos@`{@dotless{i}}, @code{$NF} @`e lo stesso di @code{$7}, che @`e @samp{carino.}. +Se si cerca di far riferimento a un campo oltre l'ultimo +(come @code{$8} quando il record ha solo sette campi), si ottiene +la stringa nulla. (Se usato in un'operazione numerica si ottiene zero.) + +L'uso di @code{$0}, che sarebbe come un riferimento al campo ``numero zero'', +@`e un caso particolare: rappresenta l'intero record in input. Si usa quando +non si @`e interessati a un campo specifico. Vediamo qualche altro esempio: + +@example +$ @kbd{awk '$1 ~ /li/ @{ print $0 @}' mail-list} +@print{} Amelia 555-5553 amelia.zodiacusque@@gmail.com F +@print{} Julie 555-6699 julie.perscrutabor@@skeeve.com F +@end example + +@noindent +Questo esempio stampa ogni record del file @file{mail-list} il cui primo campo +contiene la stringa @samp{li}. + +Per converso, il seguente esempio cerca @samp{li} @emph{nell'intero record} e +stampa il primo e l'ultimo campo di ogni record in input per cui @`e stata +trovata una corrispondenza: + +@example +$ @kbd{awk '/li/ @{ print $1, $NF @}' mail-list} +@print{} Amelia F +@print{} Broderick R +@print{} Julie F +@print{} Samuel A +@end example + +@node Campi non costanti +@section Numeri di campo variabili +@cindex campi, numero dei +@cindex numeri di campo + +Un numero di campo non @`e necessario che sia una costante. Nel linguaggio +@command{awk} si pu@`o usare qualsiasi espressione dopo @samp{$} per far +riferimento a un campo. Il valore dell'espressione specifica il numero di +campo. Se il valore @`e una stringa, piuttosto che un numero, viene convertito +in un numero. Consideriamo questo esempio: + +@example +awk '@{ print $NR @}' +@end example + +@noindent +Ricordiamo che @code{NR} @`e il numero dei record letti fino a questo punto: uno +nel primo record, due nel secondo, etc. Cos@`{@dotless{i}} quest'esempio stampa il primo +campo del primo record, il secondo campo del secondo record, e cos@`{@dotless{i}} via. +Per il ventesimo record, @`e stampato il campo numero 20; molto probabilmente il +record ha meno di 20 campi, perci@`o stampa una riga vuota. +Questo @`e un altro esempio sull'uso di espressioni come numeri di campo: + +@example +awk '@{ print $(2*2) @}' mail-list +@end example + +@command{awk} calcola l'espressione @samp{(2*2)} e usa il suo valore come +numero del campo da stampare. Qui @samp{*} rappresenta la +moltiplicazione, quindi l'espressione @samp{2*2} ha il valore quattro. Le +parentesi vengono usate affinch@'e la moltiplicazione sia eseguita prima +dell'operazione @samp{$}; sono necessarie ogni volta che c'@`e un operatore +binario@footnote{A un @dfn{operatore binario}, come @samp{*} per la +moltiplicazione, servono due operandi. La distinzione @`e necessaria poich@'e +@command{awk} ha anche operatori unari (un operando) e ternari (tre +operandi).} +nell'espressione del numero di campo. Questo esempio, dunque, stampa il +tipo di relazione (il quarto campo) per ogni riga del file +@file{mail-list}. (Tutti gli operatori di @command{awk} sono elencati, in +ordine decrescente di precedenza, in +@ref{Precedenza}.) + +Se il numero di campo calcolato @`e zero, si ottiene l'intero record. +Quindi, @samp{$(2-2)} ha lo stesso valore di @code{$0}. Numeri di campo +negativi non sono consentiti; tentare di far riferimento a uno di essi +normalmente fa terminare il programma. (Lo standard POSIX non chiarisce +cosa succede quando si fa riferimento a un numero di campo negativo. +@command{gawk} avvisa di questo e fa terminare il programma. Altre +implementazioni di @command{awk} possono comportarsi in modo diverso.) + +Come accennato in @ref{Campi}, +@command{awk} memorizza il numero di campi del record corrente nella variabile +predefinita @code{NF} (@pxref{Variabili predefinite}). Quindi, +l'espressione @code{$NF} non @`e una funzionalit@`a speciale---@`e la diretta +conseguenza della valutazione di @code{NF} e dell'uso di questo valore come +numero di campo. + +@node Cambiare i campi +@section Cambiare il contenuto di un campo + +@cindex campi, cambiare il contenuto dei +Il contenuto di un campo, cos@`{@dotless{i}} come @`e visto da @command{awk}, pu@`o essere +cambiato all'interno di un programma @command{awk}; questo cambia quello che +@command{awk} percepisce come record in input corrente. (Il reale file in +input non viene toccato; @command{awk} non modifica @emph{mai} il file in +input). +Si consideri il seguente esempio e il suo output: + +@example +$ @kbd{awk '@{ numero_pacchi = $3 ; $3 = $3 - 10} +> @kbd{print numero_pacchi, $3 @}' inventory-shipped} +@print{} 25 15 +@print{} 32 22 +@print{} 24 14 +@dots{} +@end example + +@noindent +Il programma per prima cosa salva il valore originale del campo tre nella +variabile @code{numero_pacchi}. +Il segno @samp{-} rappresenta la sottrazione, cos@`{@dotless{i}} questo programma riassegna +il campo tre, @code{$3}, come il valore originale del campo meno dieci: +@samp{$3 - 10}. (@xref{Operatori aritmetici}.) +Poi stampa il valore originale e quello nuovo del campo tre. +(Qualcuno nel magazzino ha fatto un errore ricorrente nell'inventariare le +scatole rosse.) + +Perch@'e questo funzioni, il testo in @code{$3} deve poter essere riconosciuto +come un numero; la stringa di caratteri dev'essere convertita in un numero +affich@'e il computer possa eseguire operazioni aritmetiche su di essa. Il +numero che risulta dalla sottrazione viene nuovamente convertito in +una stringa di caratteri che quindi diventa il campo tre. +@xref{Conversione}. + +Quando il valore di un campo @`e cambiato (come percepito da @command{awk}), il +testo del record in input viene ricalcolato per contenere il nuovo campo al +posto di quello vecchio. In altre parole, @code{$0} cambia per riflettere il +campo modificato. Questo programma +stampa una copia del file in input, con 10 sottratto dal secondo campo di ogni +riga: + +@example +$ @kbd{awk '@{ $2 = $2 - 10; print $0 @}' inventory-shipped} +@print{} Jan 3 25 15 115 +@print{} Feb 5 32 24 226 +@print{} Mar 5 24 34 228 +@dots{} +@end example + +@`E possibile inoltre assegnare contenuti a campi che sono fuori +intervallo. Per esempio: + +@example +$ @kbd{awk '@{ $6 = ($5 + $4 + $3 + $2)} +> @kbd{ print $6 @}' inventory-shipped} +@print{} 168 +@print{} 297 +@print{} 301 +@dots{} +@end example + +@cindex aggiungere, campi +@cindex campi, aggiungere +@noindent +Abbiamo appena creato @code{$6}, il cui valore @`e la somma dei campi +@code{$2}, @code{$3}, @code{$4} e @code{$5}. Il segno @samp{+} +rappresenta l'addizione. Per il file @file{inventory-shipped}, @code{$6} +rappresenta il numero totale di pacchi spediti in un determinato mese. + +La creazione di un nuovo campo cambia la copia interna di @command{awk} nel +record in input corrente, che @`e il valore di @code{$0}. Cos@`{@dotless{i}}, se si scrive +@samp{print $0} dopo aver aggiunto un campo, il record stampato include il +nuovo campo, col numero di separatori di campo appropriati tra esso e i +campi originariamente presenti. + +@cindex @code{OFS}, variabile +@cindex output, separatore di campo, si veda @code{OFS}, variabile +@cindex campo, separatori di, si veda anche @code{OFS} +@cindex separatori di campo, si veda anche @code{OFS} +Questa ridefinizione influenza ed @`e influenzata da +@code{NF} (il numero dei campi; @pxref{Campi}). +Per esempio, il valore di @code{NF} @`e impostato al numero del campo pi@`u +elevato che @`e stato creato. +Il formato preciso di @code{$0} @`e influenzato anche da una funzionalit@`a che +non @`e ancora stata trattata: il @dfn{separatore di campo di output}, +@code{OFS}, usato per separare i campi (@pxref{Separatori di output}). + +Si noti, comunque, che il mero @emph{riferimento} a un campo fuori +intervallo @emph{non} cambia il valore di @code{$0} o di @code{NF}. +Far riferimento a un campo fuori intervallo produce solo una stringa nulla. +Per esempio: + +@example +if ($(NF+1) != "") + print "non @`e possibile" +else + print "@`e tutto normale" +@end example + +@noindent +dovrebbe stampare @samp{@`e tutto normale}, perch@'e @code{NF+1} @`e certamente +fuori intervallo. (@xref{Istruzione if} +per maggiori informazioni sulle istruzioni @code{if-else} di @command{awk}. +@xref{Tipi di variabile e confronti} +per maggiori informazioni sull'operatore @samp{!=}.) + +@`E importante notare che facendo un assegnamento a un campo esistente cambia +il valore di @code{$0} ma non cambia il valore di @code{NF}, +anche qualora si assegni a un campo la stringa nulla. Per esempio: + +@example +$ @kbd{echo a b c d | awk '@{ OFS = ":"; $2 = ""} +> @kbd{print $0; print NF @}'} +@print{} a::c:d +@print{} 4 +@end example + +@noindent +Il campo @`e ancora l@`{@dotless{i}}; ha solo un valore vuoto, delimitato dai due "due punti" +tra @samp{a} e @samp{c}. +Questo esempio mostra cosa succede se si crea un nuovo campo: + +@example +$ @kbd{echo a b c d | awk '@{ OFS = ":"; $2 = ""; $6 = "nuovo"} +> @kbd{print $0; print NF @}'} +@print{} a::c:d::nuovo +@print{} 6 +@end example + +@noindent +Il campo intermedio, @code{$5}, @`e creato con un valore vuoto +(indicato dalla seconda coppia di due punti adiacenti), +e @code{NF} @`e aggiornato col valore sei. + +@cindex angolo buio, variabile @code{NF}, decremento +@cindex @code{NF}, variable, decremento +Decrementando @code{NF} si eliminano i campi +dopo il nuovo valore di @code{NF} e si ricalcola @code{$0}. +@value{DARKCORNER} +Vediamo un esempio: + +@example +$ @kbd{echo a b c d e f | awk '@{ print "NF =", NF;} +> @kbd{ NF = 3; print $0 @}'} +@print{} NF = 6 +@print{} a b c +@end example + +@cindex portabilit@`a, variabile @code{NF}@comma{} decremento +@quotation ATTENZIONE +Alcune versioni di @command{awk} non +ricostruiscono @code{$0} quando @code{NF} viene diminuito. +@end quotation + +Infine, ci sono casi in cui conviene forzare +@command{awk} a ricostruire l'intero record, usando i valori correnti +dei campi e @code{OFS}. Per far ci@`o, si usa +l'apparentemente innocuo assegnamento: + +@example +$1 = $1 # forza la ricostruzione del record +print $0 # o qualsiasi altra cosa con $0 +@end example + +@noindent +Questo forza @command{awk} a ricostruire il record. Aggiungere un commento +rende tutto pi@`u chiaro, come abbiamo appena visto. + +C'@`e un rovescio della medaglia nella relazione tra @code{$0} e +i campi. Qualsiasi assegnamento a @code{$0} fa s@`{@dotless{i}} che il record sia +rianalizzato (sintatticamente) e ridiviso in campi usando il valore +@emph{corrente} di @code{FS}. Questo si applica anche a qualsiasi funzione +predefinita che aggiorna @code{$0}, come @code{sub()} e @code{gsub()} +(@pxref{Funzioni per stringhe}). + +@sidebar Comprendere @code{$0} + +@`E importante ricordare che @code{$0} @`e @emph{l'intero} +record, esattamente com'@`e stato letto dall'input, compresi tutti gli spazi +vuoti iniziali e finali, e l'esatto spazio vuoto (o altri caratteri) che +separa i campi. + +@`E un errore comune tentare di cambiare il separatore di campo in un record +semplicemente impostando @code{FS} e @code{OFS}, e poi +aspettarsi che un semplice @samp{print} or @samp{print $0} stampi il record +modificato. + +Questo non funziona, poich@'e non @`e stato fatto niente per cambiare quello +stesso record. Invece, si deve forzare la ricostruzione del record, +tipicamente con un'istruzione come @samp{$1 = $1}, come descritto +in precedenza. +@end sidebar + + +@node Separatori di campo +@section Specificare come vengono separati i campi + +@menu +* Separatori di campo di default:: Come di solito sono separati i campi. +* Separare campi con @dfn{regexp}:: Usare @dfn{regexp} come separatori. +* Campi di un solo carattere:: Fare di ogni carattere un campo + separato. +* Separatori campo da riga di comando:: Assegnare @code{FS} dalla riga di + comando. +* Campo intera riga:: Far s@`{@dotless{i}} che la riga intera sia un + campo solo. +* Sommario sulla separazione campi:: Alcuni punti finali e una tavola di + sommario. +@end menu + +@cindex @code{FS}, variabile +@cindex campi, separare +@cindex campo, separatori di +Il @dfn{separatore di campo}, che @`e un carattere singolo o un'espressione +regolare, controlla il modo in cui @command{awk} suddivide un record in input +in campi. @command{awk} fa una scansione del record in input per trovare i +caratteri che individuano il separatore; i campi sono il testo compreso tra i +separatori trovati. + +Nell'esempio che segue, usiamo il simbolo del punto elenco (@bullet{}) per +rappresentare gli spazi nell'output. +Se il separatore di campo @`e @samp{oo}, la seguente riga: + +@example +moo goo gai pan +@end example + +@noindent +@`e suddivisa in tre campi: @samp{m}, @samp{@bullet{}g}, e +@samp{@bullet{}gai@bullet{}pan}. +Notare gli spazi iniziali nei valori del secondo e del terzo campo. + +@cindex risoluzione di problemi, @command{awk} usa @code{FS} anzich@'e @code{IFS} +@cindex problemi, risoluzione di, @command{awk} usa @code{FS} anzich@'e @code{IFS} +Il separatore di campo @`e rappresentato dalla variable predefinita @code{FS}. +I programmatori di shell notino: @command{awk} @emph{non} usa il +nome @code{IFS} che @`e usato dalle shell conformi a POSIX (come +la Unix Bourne shell, @command{sh}, o Bash). + +@cindex @code{FS}, variabile, cambiare il valore di una +Il valore di @code{FS} si pu@`o cambiare nel programma @command{awk} con +l'operatore di assegnamento, @samp{=} (@pxref{Operatori di assegnamento}). +Spesso il momento giusto per far ci@`o @`e all'inizio dell'esecuzione +prima che sia stato elaborato qualsiasi input, cos@`{@dotless{i}} che il primo record +sia letto col separatore appropriato. Per far questo, si usa il modello di +ricerca speciale +@code{BEGIN} +(@pxref{BEGIN/END}). +Per esempio, qui impostiamo il valore di @code{FS} alla stringa +@code{","}: + +@example +awk 'BEGIN @{ FS = "," @} ; @{ print $2 @}' +@end example + +@cindex @code{BEGIN}, criterio di ricerca +@noindent +Data la riga in input: + +@example +John Q. Smith, 29 Oak St., Walamazoo, MI 42139 +@end example + +@noindent +questo programma @command{awk} estrae e stampa la stringa +@samp{@bullet{}29@bullet{}Oak@bullet{}St.}. + +@cindex separatori di campo, scelta dei +@cindex espressioni regolari come separatori di campo +@cindex separatori di campo, espressioni regolari come +A volte i dati in input contengono caratteri separatori che non +separano i campi nel modo in cui ci si sarebbe atteso. Per esempio, il +nome della persona dell'esempio che abbiamo appena usato potrebbe avere un +titolo o un suffisso annesso, come: + +@example +John Q. Smith, LXIX, 29 Oak St., Walamazoo, MI 42139 +@end example + +@noindent +Lo stesso programma estrarrebbe @samp{@bullet{}LXIX} invece di +@samp{@bullet{}29@bullet{}Oak@bullet{}St.}. +Se ci si aspetta che il programma stampi l'indirizzo, +si rimarr@`a sorpresi. La morale @`e quella di scegliere la struttura dei dati +e i caratteri di separazione attentamente per evitare questi problemi. +(Se i dati non sono in una forma facile da elaborare, pu@`o darsi che +si possano manipolare con un programma @command{awk} separato.) + + +@node Separatori di campo di default +@subsection Lo spazio vuoto normalmente separa i campi + +@cindex spazi vuoti, come separatori di campo +I campi sono separati normalmente da spazi vuoti +(spazi, tabulazioni e ritorni a capo), non solo da spazi singoli. Due spazi +in una riga non delimitano un campo vuoto. Il valore di default del separatore +di campo @code{FS} @`e una stringa contenente un singolo spazio, @w{@code{" "}}. +Se @command{awk} interpretasse questo valore nel modo usuale, ogni carattere +di spazio separerebbe campi, quindi due spazi in una riga creerebbero un campo +vuoto tra di essi. Il motivo per cui questo non succede @`e perch@'e un singolo +spazio come valore di @code{FS} @`e un caso particolare: @`e preso per specificare +il modo di default di delimitare i campi. + +Se @code{FS} @`e qualsiasi altro carattere singolo, come @code{","}, ogni +ricorrenza di quel carattere separa due campi. Due ricorrenze consecutive +delimitano un campo vuoto. Se il carattere si trova all'inizio o alla fine +della riga, anche quello delimita un campo vuoto. Il carattere di spazio @`e +il solo carattere singolo che non segue queste +regole. + +@node Separare campi con @dfn{regexp} +@subsection Usare @dfn{regexp} come separatori di campo + +@cindex espressioni regolari, come separatori di campo +@cindex separatori di campo, espressioni regolari come +La precedente @value{SUBSECTION} +ha illustrato l'uso di caratteri singoli o di stringhe semplici come +valore di @code{FS}. +Pi@`u in generale, il valore di @code{FS} pu@`o essere una stringa contenente +qualsiasi espressione regolare. Se questo @`e il caso, ogni corrispondenza nel +record con l'espressione regolare separa campi. Per esempio, l'assegnamento: + +@example +FS = ", \t" +@end example + +@noindent +trasforma ogni parte di una riga in input che consiste di una virgola seguita +da uno spazio e una tabulazione in un separatore di campo. +@ifinfo +(@samp{\t} +@`e una @dfn{sequenza di protezione} che sta per un segno di tabulazione; +@pxref{Sequenze di protezione}, +per l'elenco completo di sequenze di protezione simili.) +@end ifinfo + +Per un esempio meno banale di espressione regolare, si provi a usare spazi +singoli per separare campi nel modo in cui sono usate le virgole. @code{FS} +pu@`o essere impostato a @w{@code{"[@ ]"}} (parentesi quadra sinistra, spazio, +parentesi quadra destra). Quest'espressione regolare corrisponde a uno spazio +@iftex +singolo e niente pi@`u. (@pxrefil{Espressioni regolari}). +@end iftex +@ifnottex +singolo e niente pi@`u. (@pxref{Espressioni regolari}). +@end ifnottex +C'@`e una differenza importante tra i due casi di @samp{FS = @w{" "}} +(uno spazio singolo) e @samp{FS = @w{"[ \t\n]+"}} +(un'espressione regolare che individua uno o pi@`u spazi, tabulazioni o +ritorni a capo). Per entrambi i valori di @code{FS}, i campi sono +separati da @dfn{serie} (ricorrenze adiacenti multiple) di spazi, tabulazioni +e/o ritorni a capo. Comunque, quando il valore di @code{FS} @`e +@w{@code{" "}}, @command{awk} prima toglie lo spazio vuoto iniziale e finale +dal record e poi stabilisce dove sono i campi. +Per esempio, la seguente @dfn{pipeline} stampa @samp{b}: + +@example +$ @kbd{echo ' a b c d ' | awk '@{ print $2 @}'} +@print{} b +@end example + +@noindent +Invece la @dfn{pipeline} che segue stampa @samp{a} (notare lo spazio extra +intorno a ogni lettera): + +@example +$ @kbd{echo ' a b c d ' | awk 'BEGIN @{ FS = "[ \t\n]+" @}} +> @kbd{@{ print $2 @}'} +@print{} a +@end example + +@noindent +@c @cindex null strings +@cindex stringhe nulle +@cindex stringhe vuote, si veda stringhe nulle +In questo caso, il primo campo @`e nullo, o vuoto. +Il taglio degli spazi vuoti iniziale e finale ha luogo anche +ogniqualvolta @code{$0} @`e ricalcolato. +Per esempio, si consideri questa @dfn{pipeline}: + +@example +$ @kbd{echo ' a b c d' | awk '@{ print; $2 = $2; print @}'} +@print{} a b c d +@print{} a b c d +@end example + +@noindent +La prima istruzione @code{print} stampa il record cos@`{@dotless{i}} come @`e stato letto, +con lo spazio vuoto intatto. L'assegnamento a @code{$2} ricostruisce +@code{$0} concatenando insieme @code{$1} fino a @code{$NF}, +separati dal valore di @code{OFS} (che @`e uno spazio per default). +Poich@'e lo spazio vuoto iniziale @`e stato ignorato quando si @`e trovato +@code{$1}, esso non fa parte del nuovo @code{$0}. Alla fine, l'ultima +istruzione @code{print} stampa il nuovo @code{$0}. + +@cindex @code{FS}, contenente @code{^} +@cindex @code{^} (circonflesso), in @code{FS} +@cindex angolo buio, @code{^}, in @code{FS} +C'@`e un'ulteriore sottigliezza da considerare quando si usano le espressioni +regolari per separare i campi. +Non @`e ben specificato nello standard POSIX, n@'e altrove, cosa +significhi @samp{^} nella divisione dei campi. Il @samp{^} cerca +corrispondenze solo all'inizio dell'intero record? Oppure ogni separatore di +campo @`e una nuova stringa? Di fatto versioni differenti di @command{awk} +rispondono a questo quesito in modo diverso, e non si dovrebbe far affidamento +su alcun comportamento specifico nei propri programmi. +@value{DARKCORNER} + +@cindex Brian Kernighan, @command{awk} di +Di sicuro, BWK @command{awk} individua con @samp{^} +solo l'inizio del record. Anche @command{gawk} +funziona in questo modo. Per esempio: + +@example +$ @kbd{echo 'xxAA xxBxx C' |} +> @kbd{gawk -F '(^x+)|( +)' '@{ for (i = 1; i <= NF; i++)} +> @kbd{ printf "-->%s<--\n", $i @}'} +@print{} --><-- +@print{} -->AA<-- +@print{} -->xxBxx<-- +@print{} -->C<-- +@end example + +@node Campi di un solo carattere +@subsection Fare di ogni carattere un campo separato + +@cindex estensioni comuni, campi di un solo carattere +@cindex comuni, estensioni, campi di un solo carattere +@cindex differenze tra @command{awk} e @command{gawk}, campi di un solo carattere +@cindex singolo carattere, campi +@cindex campi di un solo carattere +Ci sono casi in cui si abbia la necessit@`a di analizzare ciascun carattere di un +record separatamente. Questo si pu@`o fare in @command{gawk} semplicemente +assegnando la stringa nulla (@code{""}) a @code{FS}. @value{COMMONEXT} +In questo caso, +ogni singolo carattere nel record diventa un campo separato. +Per esempio: + +@example +$ @kbd{echo a b | gawk 'BEGIN @{ FS = "" @}} +> @kbd{@{} +> @kbd{for (i = 1; i <= NF; i = i + 1)} +> @kbd{print "Il campo", i, "@`e", $i} +> @kbd{@}'} +@print{} Il campo 1 @`e a +@print{} Il campo 2 @`e +@print{} Il campo 3 @`e b +@end example + +@cindex angolo buio, @code{FS} come stringa nulla +@cindex @code{FS}, variabile, come stringa nulla +Tradizionalmente, il comportamento di @code{FS} quando @`e impostato a +@code{""} non @`e stato definito. In questo caso, la maggior parte delle +versioni UNIX di @command{awk} trattano l'intero record come se avesse un +unico campo. +@value{DARKCORNER} +In modalit@`a di compatibilit@`a +(@pxref{Opzioni}), +se @code{FS} @`e la stringa nulla, anche @command{gawk} +si comporta in questo modo. + +@node Separatori campo da riga di comando +@subsection Impostare @code{FS} dalla riga di comando +@cindex @option{-F}, opzione sulla riga di comando +@cindex separatore di campo, specificare sulla riga di comando +@cindex riga di comando, impostare @code{FS} sulla +@cindex @code{FS}, variabile, impostare da riga di comando + +@code{FS} pu@`o essere impostata sulla riga di comando. Per far questo si usa +l'opzione @option{-F}. Per esempio: + +@example +awk -F, '@var{programma}' @var{i-file-di-input} +@end example + +@noindent +imposta @code{FS} al carattere @samp{,}. Si noti che l'opzione richiede +un carattere maiuscolo @samp{F} anzich@'e minuscolo @samp{f}. Quest'ultima +opzione (@option{-f}) serve a specificare il file contenente un programma +@command{awk}. + +Il valore usato per l'argomento di @option{-F} @`e elaborato esattamente nello +stesso modo degli assegnamenti alla variabile predefinita @code{FS}. Qualsiasi +carattere speciale nel separatore di campo dev'essere protetto in modo +appropriato. Per esempio, per usare un @samp{\} come separatore di campo +sulla riga di comando, si dovrebbe battere: + +@example +# equivale a FS = "\\" +awk -F\\\\ '@dots{}' file @dots{} +@end example + +@noindent +@cindex @code{\} (barra inversa), come separatore di campo +@cindex barra inversa (@code{\}), come separatore di campo +Poich@'e @samp{\} @`e usato nella shell per proteggere caratteri, a @command{awk} +arriva @samp{-F\\}. Quindi @command{awk} elabora @samp{\\} per caratteri di +protezione (@pxref{Sequenze di protezione}), producendo alla fine +un unico @samp{\} da usare come separatore di campo. + +@c @cindex historical features +Come caso particolare, in modalit@`a di compatibilit@`a +(@pxref{Opzioni}), +se l'argomento di @option{-F} @`e @samp{t}, @code{FS} @`e impostato al +carattere di tabulazione. Se si immette @samp{-F\t} nella +shell, senza che sia tra apici, @samp{\} viene cancellata, +cos@`{@dotless{i}} @command{awk} +conclude che si vuole realmente che i campi siano separati da tabulazioni e +non da delle @samp{t}. Si usi @samp{-v FS="t"} o @samp{-F"[t]"} sulla riga di +comando se si vuole separare i campi con delle @samp{t}. +Quando non si @`e in modalit@`a di compatibilit@`a si deve usare @samp{-F '\t'} per +specificare che le tabulazioni separano i campi. + +Come esempio, usiamo un file di programma @command{awk} chiamato +@file{edu.awk} che contiene il criterio di ricerca @code{/edu/} e l'azione +@samp{print $1}: + +@example +/edu/ @{ print $1 @} +@end example + +Impostiamo inoltre @code{FS} al carattere @samp{-} ed eseguiamo il programma +sul file @file{mail-list}. Il seguente comando stampa un elenco dei nomi +delle persone che lavorano all'universit@`a o che la frequentano, e le prime tre +cifre dei loro numeri di telefono: + +@example +$ @kbd{awk -F- -f edu.awk mail-list} +@print{} Fabius 555 +@print{} Samuel 555 +@print{} Jean +@end example + +@noindent +Si noti la terza riga di output. La terza riga +nel file originale @`e simile a questa: + +@example +Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R +@end example + +Il @samp{-} che fa parte del nome della persona @`e stato usato come +separatore di campo, al posto del @samp{-} presente nel numero di telefono, +che ci si aspettava venisse usato. +Questo lascia intuire il motivo per cui si deve stare attenti nella scelta +dei separatori di campo e di record. + +@cindex Unix @command{awk}, file di password, separatori di campo e +Forse l'uso pi@`u comune di un solo carattere come separatore di campo avviene +quando si elabora il file delle password di un sistema Unix. Su molti sistemi +Unix, ogni utente @`e descritto da un elemento nel file delle password del +sistema, che contiene una riga singola per ogni utente. In queste righe le +informazioni sono separate da dei caratteri ":". Il +primo campo @`e il nome di login dell'utente e il secondo @`e la password +dell'utente criptata o oscurata (una password oscurata @`e indicata dalla +presenza di una sola @samp{x} nel secondo campo). Una riga nel file delle +password potrebbe essere simile a questa: + +@cindex Robbins, Arnold +@example +arnold:x:2076:10:Arnold Robbins:/home/arnold:/bin/bash +@end example + +Il seguente programma esamina il file delle password di sistema e stampa le +voci relative agli utenti il cui nome completo non @`e presente nel file: + +@example +awk -F: '$5 == ""' /etc/passwd +@end example + +@node Campo intera riga +@subsection Fare di una riga intera un campo solo + +Occasionalmente, @`e utile trattare l'intera riga in input come un solo campo. +Questo si pu@`o fare facilmente e in modo portabile semplicemente impostando +@code{FS} a @code{"\n"} (un ritorno a capo).@footnote{Grazie ad +Andrew Schorr per questo suggerimento.} + +@example +awk -F'\n' '@var{programma}' @var{file @dots{}} +@end example + +@noindent +In questo caso, @code{$1} coincide con @code{$0}. + + +@sidebar Cambiare @code{FS} non incide sui campi + +@cindex POSIX @command{awk}, separatori di campo e +@cindex separatore di campo, POSIX e il +Secondo lo standard POSIX, si suppone che @command{awk} si comporti +come se ogni record sia stato diviso in campi nel momento in cui @`e stato +letto. In particolare, ci@`o vuol dire che se si cambia il valore di +@code{FS} dopo che un record @`e stato letto, il valore dei campi (cio@'e +la loro suddivisione) sar@`a ancora quello ottenuto usando il precedente +valore di @code{FS}, non quello nuovo. + +@cindex angolo buio, separatori di campo +@cindex @command{sed}, programma di utilit@`a +@cindex programma di utilit@`a @command{sed} +@cindex editori di flusso +Comunque, molte delle pi@`u vecchie implementazioni di @command{awk} non +funzionano in questo modo. Invece, rimandano la divisione dei campi +fino a quando si fa effettivamente riferimento a un campo. I campi sono +divisi usando il valore @emph{corrente} di @code{FS}! +@value{DARKCORNER} +Questo comportamento pu@`o essere di difficile +identificazione. Il seguente esempio illustra la differenza +tra i due metodi. Lo script + +@example +sed 1q /etc/passwd | awk '@{ FS = ":" ; print $1 @}' +@end example + +@noindent +normalmente stampa: + +@example +@print{} root +@end example + +@noindent +su un'implementazione non standard di @command{awk}, mentre @command{gawk} +stampa l'intera prima riga del file, qualcosa come: + +@example +root:x:0:0:Root:/: +@end example + +(Il comando @command{sed}@footnote{Il programma di utilit@`a @command{sed} @`e un +``editore di flusso''. Anche il suo comportamento @`e definito dallo standard +POSIX.} appena visto stampa solo la prima riga di @file{/etc/passwd}.) +@end sidebar + +@node Sommario sulla separazione campi +@subsection Sommario sulla separazione dei campi + +@`E importante ricordare che quando si assegna una costante stringa +come valore di @code{FS}, questa subisce una normale elaborazione di stringa +da parte di @command{awk}. Per esempio, con Unix @command{awk} e +@command{gawk}, l'assegnamento @samp{FS = "\.."} assegna la stringa di +caratteri @code{".."} +a @code{FS} (la barra inversa @`e tolta). Questo crea un'espressione regolare +che significa ``i campi sono separati da ricorrenze di due caratteri +qualsiasi''. Se invece si vuole che i campi siano separati da un punto +seguito da un qualsiasi carattere singolo, si deve usare @samp{FS = "\\.."}. + +Il seguente elenco riassume come i campi vengono divisi, in base al valore +di @code{FS} (@samp{==} significa ``@`e uguale a''): + +@table @code +@item FS == " " +I campi sono separati da serie di spazi vuoti. Gli spazi vuoti iniziale e +finale sono ignorati. Questo @`e il comportamento di default. + +@item FS == @var{qualsiasi altro carattere singolo} +I campi sono separati da ogni ricorrenza del carattere. Ricorrenze +successive multiple delimitano campi vuoti, e lo stesso fanno le ricorrenze +iniziali e finali del carattere. +Il carattere pu@`o essere anche un metacarattere di espressione regolare, che +non @`e necessario proteggere. + +@item FS == @var{espressione regolare} +I campi sono separati da ricorrenze di caratteri che corrispondono alla +@var{espressione regolare}. Corrispondenze iniziali e finali della +@dfn{regexp} delimitano campi vuoti. +@item FS == "" +Ogni sinngolo carattere nel record diventa un campo separato. +(Questa @`e un'estensione comune; non @`e specificata dallo standard POSIX.) +@end table + +@sidebar @code{FS} e @code{IGNORECASE} +La variabile @code{IGNORECASE} +(@pxref{Variabili modificabili dall'utente}) +influisce sulla divisione del campo @emph{solo} quando il valore di @code{FS} +@`e un'espressione regolare. Non ha nessun effetto quando @code{FS} @`e un +singolo carattere, anche se quel carattere @`e una lettera. Quindi, nel +seguente codice: + +@example +FS = "c" +IGNORECASE = 1 +$0 = "aCa" +print $1 +@end example + +@noindent +L'output @`e @samp{aCa}. Se si vuol veramente dividere i campi su un carattere +alfabetico ignorandone il maiuscolo/minuscolo, si deve usare un'espressione +regolare che lo far@`a in automatico (p.es., @samp{FS = "[c]"}). In questo +caso, @code{IGNORECASE} avr@`a effetto. +@end sidebar + + +@node Dimensione costante +@section Leggere campi di larghezza costante + + +@cindex campi di larghezza costante +@cindex larghezza costante, campi di +@cindex funzionalit@`a avanzate, campi di larghezza costante +@c O'Reilly doesn't like it as a note the first thing in the section. +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} tratta una funzionalit@`a avanzata +di @command{gawk}. Se si @`e un utente alle prime armi di @command{awk}, +la si pu@`o saltare in prima lettura. + +@command{gawk} fornisce una funzionalit@`a per il trattamento di campi +a larghezza fissa senza un separatore di campo distintivo. Per esempio, +dati di questo tipo si trovano nell'input per vecchi programmi Fortran dove +dei numeri sono elencati uno dopo l'altro, o nell'output di programmi che +non prevedono che il loro output sia dato in input ad altri programmi. + +Un esempio di quest'ultimo caso @`e una tabella dove tutte le colonne sono +allineate usando un numero variabile di spazi e dove @emph{i campi vuoti +sono solo spazi}. Chiaramente, la normale divisione in campi di +@command{awk} basata su @code{FS} non funziona bene in questa situazione. +Sebbene un programma @command{awk} +portabile possa usare una serie di chiamate @code{substr()} su @code{$0} +(@pxref{Funzioni per stringhe}), +questo @`e scomodo e inefficiente se il numero dei campi @`e elevato. + +@cindex risoluzione di problemi, errori fatali, specificare larghezza dei campi +@cindex problemi, risoluzione di, errori fatali, specificare larghezza dei campi +@cindex @command{w}, programma di utilit@`a +@cindex programma di utilit@`a @command{w} +@cindex @code{FIELDWIDTHS}, variabile +@cindex @command{gawk}, variabile @code{FIELDWIDTHS} in +La suddivisione di un record in input in campi a larghezza fissa viene +specificata assegnando una stringa contenente numeri separati da spazi alla +variabile predefinita @code{FIELDWIDTHS}. Ogni numero specifica la larghezza +del campo, @emph{comprese} le colonne tra i campi. Se si vogliono ignorare le +colonne tra i campi si pu@`o specificare la loro larghezza come un campo +separato che verr@`a poi ignorato. +@`E un errore fatale definire una larghezza di campo che abbia un valore +negativo. I dati seguenti costituiscono l'output del programma di utilit@`a +Unix @command{w}. @`E utile per spiegare l'uso di @code{FIELDWIDTHS}: + +@example +@group + 10:06pm up 21 days, 14:04, 23 users +User tty login@ idle JCPU PCPU what +hzuo ttyV0 8:58pm 9 5 vi p24.tex +hzang ttyV3 6:37pm 50 -csh +eklye ttyV5 9:53pm 7 1 em thes.tex +dportein ttyV6 8:17pm 1:47 -csh +gierd ttyD3 10:00pm 1 elm +dave ttyD4 9:47pm 4 4 w +brent ttyp0 26Jun91 4:46 26:46 4:41 bash +dave ttyq4 26Jun9115days 46 46 wnewmail +@end group +@end example + +Il seguente programma prende l'input sopra mostrato, converte il tempo di +inattivit@`a +in numero di secondi, e stampa i primi due campi e il tempo di inattivit@`a +calcolato: + +@example +BEGIN @{ FIELDWIDTHS = "9 6 10 6 7 7 35" @} +NR > 2 @{ + inat = $4 + sub(/^ +/, "", inat) # togli spazi prima del valore + if (inat == "") + inat = 0 + if (inat ~ /:/) @{ + split(inat, t, ":") + inat = t[1] * 60 + t[2] + @} + if (inat ~ /days/) + inat *= 24 * 60 * 60 + + print $1, $2, inat +@} +@end example + +@quotation NOTA +Questo programma usa diverse funzionalit@`a di @command{awk} non +ancora trattate. +@end quotation + +L'esecuzione del programma sui dati produce il seguente risultato: + +@example +hzuo ttyV0 0 +hzang ttyV3 50 +eklye ttyV5 0 +dportein ttyV6 107 +gierd ttyD3 1 +dave ttyD4 0 +brent ttyp0 286 +dave ttyq4 1296000 +@end example + +Un altro esempio (forse pi@`u pratico) di dati di input con larghezza costante @`e +l'input da un mazzo di schede elettorali. In alcune parti degli Stati Uniti, +i votanti marcano le loro scelte perforando delle schede elettroniche. + +Queste schede vengono poi elaborate per contare i voti espressi per ogni +singolo candidato o su ogni determinato quesito. Siccome un votante pu@`o +scegliere di non votare su alcune questioni, qualsiasi colonna della scheda +pu@`o essere vuota. Un programma @command{awk} per elaborare tali dati potrebbe +usare la funzionalit@`a @code{FIELDWIDTHS} per semplificare la lettura dei dati. +(Naturalmente, riuscire a eseguire @command{gawk} su un sistema con lettori di +schede @`e un'altra storia!) + +@cindex @command{gawk}, separazione in campi e +L'assegnazione di un valore a @code{FS} fa s@`{@dotless{i}} che @command{gawk} usi @code{FS} +per separare nuovamente i campi. Si pu@`o usare @samp{FS = FS} per ottenere +questo effetto, senza dover conoscere il valore corrente di @code{FS}. +Per vedere quale tipo di separazione sia in atto, +si pu@`o usare @code{PROCINFO["FS"]} +(@pxref{Variabili auto-assegnate}). +Il suo valore @`e @code{"FS"} se si usa la normale separazione in campi, +o @code{"FIELDWIDTHS"} se si usa la separazione in campi a larghezza fissa: + +@example +if (PROCINFO["FS"] == "FS") + @var{separazione in campi normale}@dots{} +else if (PROCINFO["FS"] == "FIELDWIDTHS") + @var{separazione in campi a larghezza fissa}@dots{} +else + @var{separazione dei campi in base al contenuto}@dots{} @ii{(si veda +@ifnotinfo +la @value{SECTION} successiva)} +@end ifnotinfo +@ifinfo +il @value{SECTION} successivo)} +@end ifinfo +@end example + +Quest'informazione @`e utile quando si scrive una funzione che +necessita di cambiare temporaneamente @code{FS} o @code{FIELDWIDTHS}, +leggere alcuni record, e poi ripristinare le impostazioni originali +(@pxref{Funzioni Passwd}, +per un esempio di tale funzione). + +@node Separazione in base al contenuto +@section Definire i campi in base al contenuto + +@c O'Reilly doesn't like it as a note the first thing in the section. +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} tratta una funzionalit@`a avanzata +di @command{gawk}. Se si @`e un utente alle prime armi di @command{awk}, +la si pu@`o saltare in prima lettura. + +@cindex funzionalit@`a avanzate, specificare il contenuto dei campi +Normalmente, quando si usa @code{FS}, @command{gawk} definisce i campi come +le parti del record che si trovano tra due separatori di campo. In altre +parole, @code{FS} definisce cosa un campo @emph{non @`e}, invece di cosa +@emph{@`e}. +Tuttavia, ci sono casi in cui effettivamente si ha bisogno di definire i campi +in base a cosa essi sono, e non in base a cosa non sono. + +Il caso pi@`u emblematico @`e quello dei dati cosiddetti @dfn{comma-separated +value} (CSV). Molti fogli elettronici, per esempio, possono esportare i dati +in file di testo, dove ogni record termina con un ritorno a capo e i campi +sono separati tra loro da virgole. Se le virgole facessero solo da separatore +fra i dati non ci sarebbero problemi. Il problema sorge se uno dei campi +contiene una virgola @emph{al suo interno}. +In queste situazioni, la maggioranza dei programmi include il campo fra +doppi apici.@footnote{Il formato CSV non ha avuto, per molti anni, una +definizione standard formale. +@uref{http://www.ietf.org/rfc/rfc4180.txt, RFC 4180} +standardizza le pratiche pi@`u comuni.} +Cos@`{@dotless{i}}, potremmo avere dei dati di questo tipo: + +@example +@c file eg/misc/addresses.csv +Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA +@c endfile +@end example + +@cindex @command{gawk}, variabile @code{FPAT} in +@cindex @code{FPAT}, variabile +La variabile @code{FPAT} offre una soluzione per casi come questo. +Il valore di @code{FPAT} dovrebbe essere una stringa formata da un'espressione +regolare. L'espressione regolare descrive il contenuto di ciascun campo. + +Nel caso dei dati CSV visti prima, ogni campo @`e ``qualsiasi cosa che non +sia una virgola,'' oppure ``doppi apici, seguiti da qualsiasi cosa che non +siano doppi apici, e doppi apici di chiusura''. Se fosse scritta come una +costante @dfn{regexp} +@iftex +(@pxrefil{Espressioni regolari}), +@end iftex +@ifnottex +(@pxref{Espressioni regolari}), +@end ifnottex +sarebbe @code{/([^,]+)|("[^"]+")/}. +Dovendola scrivere come stringa si devono proteggere i doppi apici, +e quindi si deve scrivere: + +@example +FPAT = "([^,]+)|(\"[^\"]+\")" +@end example + +Come esempio pratico, si pu@`o vedere questo semplice programma che analizza +e divide i dati: + +@example +@c file eg/misc/simple-csv.awk +BEGIN @{ + FPAT = "([^,]+)|(\"[^\"]+\")" +@} + +@{ + print "NF = ", NF + for (i = 1; i <= NF; i++) @{ + printf("$%d = <%s>\n", i, $i) + @} +@} +@c endfile +@end example + +Eseguendolo, avendo in input la riga vista sopra, si ottiene: + +@example +$ @kbd{gawk -f simple-csv.awk addresses.csv} +NF = 7 +$1 = <Robbins> +$2 = <Arnold> +$3 = <"1234 A Pretty Street, NE"> +$4 = <MyTown> +$5 = <MyState> +$6 = <12345-6789> +$7 = <USA> +@end example + +Si noti la virgola contenuta nel valore del campo @code{$3}. + +Un semplice miglioramento se si elaborano dati CSV di questo tipo potrebbe +essere quello di rimuovere i doppi apici, se presenti, con del codice di +questo tipo: + +@example +if (substr($i, 1, 1) == "\"") @{ + len = length($i) + $i = substr($i, 2, len - 2) # Ottiene il testo tra doppi apici +@} +@end example + +Come per @code{FS}, la variabile @code{IGNORECASE} +(@pxref{Variabili modificabili dall'utente}) ha effetto sulla separazione dei +campi con @code{FPAT}. + +Se si assegna un valore a @code{FPAT} la divisione in campi non viene +effettuata utilizzando @code{FS} o @code{FIELDWIDTHS}. +Analogamente a @code{FIELDWIDTHS}, il valore di @code{PROCINFO["FS"]} +sar@`a @code{"FPAT"} se @`e in uso la suddivisione in campi in base al contenuto. + +@quotation NOTA +Alcuni programmi esportano dei dati CSV che contengono dei ritorni a capo al +loro interno in campi rinchiusi tra doppi apici. @command{gawk} non @`e in +grado di trattare questi dati. Malgrado esista una specifica ufficiale +per i dati CSV, non c'@`e molto da fare; il meccanismo di @code{FPAT} fornisce +una soluzione elegante per la maggioranza dei casi, e per gli sviluppatori di +@command{gawk} ci@`o pu@`o bastare. +@end quotation + +Come visto, l'espressione regolare usata per @code{FPAT} richiede +che ogni campo contenga almeno un carattere. Una semplice modifica +(cambiare il primo @samp{+} con @samp{*}) permette che siano presenti dei +campi vuoti: + +@example +FPAT = "([^,]*)|(\"[^\"]+\")" +@end example + +@c FIXME: 4/2015 +@c Consider use of FPAT = "([^,]*)|(\"[^\"]*\")" +@c (star in latter part of value) to allow quoted strings to be empty. +@c Per email from Ed Morton <mortoneccc@comcast.net> + +Infine, la funzione @code{patsplit()} rende la stessa funzionalit@`a disponibile +per suddividere normali stringhe (@pxref{Funzioni per stringhe}). + +Per ricapitolare, @command{gawk} fornisce tre metodi indipendenti per +suddividere in campi i record in input. +Il meccanismo usato @`e determinato da quella tra le tre +variabili---@code{FS}, @code{FIELDWIDTHS}, o @code{FPAT}---a cui +sia stato assegnato un valore pi@`u recentemente. + +@node Righe multiple +@section Record su righe multiple + +@cindex righe multiple, record su +@cindex record multiriga +@cindex input, record multiriga +@cindex file, lettura dei record multiriga +@cindex input, file in, si veda file in input +In alcune banche-dati, una sola riga non pu@`o contenere in modo adeguato +tutte le informazioni di una voce. In questi casi si possono usare record +multiriga. +Il primo passo @`e quello di scegliere il formato dei dati. + +@cindex separatori di record, per record multiriga +Una tecnica @`e quella di usare un carattere o una stringa non usuali per +separare i record. Per esempio, si pu@`o usare il carattere di interruzione di +pagina (scritto @samp{\f} sia in @command{awk} che in C) per separarli, +rendendo ogni record una pagina del file. Per far ci@`o, basta impostare la +variabile @code{RS} a @code{"\f"} (una stringa contenente il carattere di +interruzione di pagina). Si potrebbe ugualmente usare qualsiasi altro +carattere, sempre che non faccia parte dei dati di un record. + +@cindex @code{RS}, variabile, record multiriga e +Un'altra tecnica @`e quella di usare righe vuote per separare i record. +Per una particolare +convenzione, una stringa nulla come valore di @code{RS} indica che i record +sono separati da una o pi@`u righe vuote. Quando @code{RS} @`e impostato alla +stringa nulla, ogni record termina sempre alla prima riga vuota che @`e stata +trovata. Il record successivo non inizia prima della successiva riga non +vuota. Indipendentemente dal numero di righe vuote presenti in successione, +esse costituiscono sempre un unico separatore di record. +(Le righe vuote devono essere completamente vuote; righe che contengono +spazi bianchi @emph{non} sono righe vuote.) + +@cindex stringa pi@`u lunga da sinistra, individuare la +@cindex individuare la stringa pi@`u lunga da sinistra +Si pu@`o ottenere lo stesso effetto di @samp{RS = ""} assegnando la stringa +@code{"\n\n+"} a @code{RS}. Quest'espressione regolare individua +il ritorno a capo alla fine del record e una o pi@`u righe vuote dopo il +record. In aggiunta, un'espressione regolare individua sempre la sequenza pi@`u +lunga possibile quando una tale stringa sia presente. +(@pxref{Pi@`u lungo da sinistra}). +Quindi, il record successivo non inizia prima della successiva riga non +vuota; indipendentemente dal numero di righe vuote presenti in una voce di +banca-dati, esse sono considerate come un unico separatore di record. + +@cindex angolo buio, record multiriga +Comunque, c'@`e una sostanziale differenza tra @samp{RS = ""} e @samp{RS = +"\n\n+"}. Nel primo caso, i ritorni a capo iniziali nel @value{DF} di +input vengono ignorati, e se un file termina senza righe vuote aggiuntive dopo +l'ultimo record, il ritorno a capo viene rimosso dal record. Nel secondo +caso, questa particolare elaborazione non viene fatta. +@value{DARKCORNER} + +@cindex separatore di campo, nei record multiriga +@cindex @code{FS}, nei record multiriga +Ora che l'input @`e separato in record, il secondo passo @`e quello di separare i +campi all'interno dei record. Un modo per farlo @`e quello di dividere in +campi ognuna delle righe in input +nel modo solito. Questo viene fatto per default tramite una +speciale funzionalit@`a. Quando @code{RS} @`e impostato alla stringa nulla +@emph{e} @code{FS} @`e impostato a un solo carattere, il carattere di +ritorno a capo agisce @emph{sempre} come separatore di campo. +Questo in aggiunta a tutte le separazioni di campo che risultano da +@code{FS}.@footnote{Quando @code{FS} @`e la stringa nulla (@code{""}), o +un'espressione regolare, questa particolare funzionalit@`a di @code{RS} non +viene applicata; si applica al separatore di campo quando @`e costituito da un +solo spazio: +@samp{FS = @w{" "}}.} + +La motivazione originale per questa particolare eccezione probabilmente era +quella di prevedere un comportamento che fosse utile nel caso di default +(cio@`e, @code{FS} uguale a @w{@code{" "}}). Questa funzionalit@`a pu@`o +costituire un problema se non si vuole che il carattere di ritorno a capo +faccia da separatore tra i campi, perch@'e non c'@`e alcun modo per impedirlo. +Tuttavia, si pu@`o aggirare il problema usando la funzione @code{split()} +per spezzare i record manualmente. +(@pxref{Funzioni per stringhe}). +Se si ha un separatore di campo costituito da un solo carattere, si pu@`o +aggirare la funzionalit@`a speciale in modo diverso, trasformando @code{FS} +in un'espressione regolare contenente +quel carattere singolo. Per esempio, se il separatore di campo @`e +un carattere di percentuale, al posto di +@samp{FS = "%"}, si pu@`o usare @samp{FS = "[%]"}. + +Un altro modo per separare i campi @`e quello di +mettere ciascun campo su una riga separata: per far questo basta impostare la +variabile @code{FS} alla stringa @code{"\n"}. +(Questo separatore di un solo carattere individua un singolo ritorno a capo.) +Un esempio pratico di un @value{DF} organizzato in questo modo potrebbe essere +un elenco di indirizzi, in cui delle righe vuote fungono da separatore fra +record. Si consideri un elenco di indirizzi in un file chiamato +@file{indirizzi}, simile a questo: + +@example +Jane Doe +123 Main Street +Anywhere, SE 12345-6789 + +John Smith +456 Tree-lined Avenue +Smallville, MW 98765-4321 +@dots{} +@end example + +@noindent +Un semplice programma per elaborare questo file @`e il seguente: + +@example +# addrs.awk --- semplice programma per una lista di indirizzi postali + +# I record sono separati da righe bianche +# Ogni riga @`e un campo. +BEGIN @{ RS = "" ; FS = "\n" @} + +@{ + print "Il nome @`e:", $1 + print "L'indirizzo @`e:", $2 + print "Citt@`a e Stato sono:", $3 + print "" +@} +@end example + +L'esecuzione del programma produce questo output: + +@example +$ @kbd{awk -f addrs.awk addresses} +@print{} Il nome @`e: Jane Doe +@print{} L'indirizzo @`e: 123 Main Street +@print{} Citt@`a e Stato sono: Anywhere, SE 12345-6789 +@print{} +@print{} Il nome @`e: John Smith +@print{} L'indirizzo @`e: 456 Tree-lined Avenue +@print{} Citt@`a e Stato sono: Smallville, MW 98765-4321 +@print{} +@dots{} +@end example + +@xref{Programma labels}, per un programma pi@`u realistico per gestire +elenchi di indirizzi. Il seguente elenco riassume come sono divisi i record, +a seconda del valore assunto da +@ifinfo +@code{RS}. +(@samp{==} significa ``@`e uguale a.'') +@end ifinfo +@ifnotinfo +@code{RS}: +@end ifnotinfo + +@table @code +@item RS == "\n" +I record sono separati dal carattere di ritorno a capo (@samp{\n}). In +effetti, ogni riga nel @value{DF} @`e un record separato, comprese le righe +vuote. Questo @`e il comportamento di default. + +@item RS == @var{qualsiasi carattere singolo} +I record sono separati da ogni ricorrenza del carattere specificato. Pi@`u +ricorrenze adiacenti delimitano record vuoti. + +@item RS == "" +I record sono separati da una o pi@`u righe vuote. +Quando @code{FS} @`e un carattere singolo, +il carattere di ritorno a capo +serve sempre come separatore di campo, in aggiunta a qualunque valore possa +avere @code{FS}. I ritorni a capo all'inizio e alla fine del file sono +ignorati. + +@item RS == @var{regexp} +I record sono separati da ricorrenze di caratteri corrispondenti a +@var{regexp}. Le corrispondenze iniziali e finali di +@var{regexp} designano record vuoti. +(Questa @`e un'estensione di @command{gawk}; non @`e specificata dallo +standard POSIX.) +@end table + +@cindex @command{gawk}, @code{RT} variabile in +@cindex @code{RT}, variabile +Se non @`e eseguito in modalit@`a di compatibilit@`a (@pxref{Opzioni}), +@command{gawk} imposta @code{RT} al testo di input corrispondente +al valore specificato da @code{RS}. +Ma se al termine del file in input non @`e stato trovato un testo che +corrisponde a @code{RS}, @command{gawk} imposta @code{RT} alla stringa nulla. + +@node Getline +@section Richiedere input usando @code{getline} + +@cindex @code{getline}, comando, input esplicito con +@cindex input esplicito +Finora abbiamo ottenuto i dati di input dal flusso di input principale di +@command{awk}: lo standard input (normalmente la tastiera, a volte +l'output di un altro programma) o i +file indicati sulla riga di comando. Il linguaggio @command{awk} ha uno +speciale comando predefinito chiamato @code{getline} che +pu@`o essere usato per leggere l'input sotto il diretto controllo dell'utente. + +Il comando @code{getline} @`e usato in molti modi diversi e +@emph{non} dovrebbe essere usato dai principianti. +L'esempio che segue alla spiegazione del comando @code{getline} +comprende del materiale che ancora non @`e stato trattato. Quindi, @`e meglio +tornare indietro e studiare il comando @code{getline} @emph{dopo} aver rivisto +il resto +@ifinfo +di questo @value{DOCUMENT} +@end ifinfo +@ifhtml +di questo @value{DOCUMENT} +@end ifhtml +@ifnotinfo +@ifnothtml +delle Parti I e II +@end ifnothtml +@end ifnotinfo +e avere acquisito una buona conoscenza di come funziona @command{awk}. + +@cindex @command{gawk}, variabile @code{ERRNO} in +@cindex @code{ERRNO}, variabile, con comando @command{getline} +@cindex differenze tra @command{awk} e @command{gawk}, comando @code{getline} +@cindex @code{getline}, comando, valori di ritorno +@cindex @option{--sandbox}, opzione, ridirezione dell'input con @code{getline} + +Il comando @code{getline} restituisce 1 se trova un record e 0 se +trova la fine del file. Se si verifica qualche errore cercando di leggere +un record, come un file che non pu@`o essere aperto, @code{getline} +restituisce @minus{}1. In questo caso, @command{gawk} imposta la variabile +@code{ERRNO} a una stringa che descrive l'errore in questione. + +Se il messaggio di errore @code{ERRNO} indica che l'operazione di I/O pu@`o +essere ritentata e la variabile @code{PROCINFO["@var{input}", "RETRY"]} @`e +impostata a 1, @code{getline} restituisce un codice di ritorno @minus{}2 +invece che @minus{}1, e si pu@`o provare a chiamare ulterioriormente +@code{getline}. @xref{Proseguire dopo errore in input} per ulteriori +informazioni riguardo a questa funzionalit@`a. + +Negli esempi seguenti, @var{comando} sta per un valore di stringa che +rappresenta un comando della shell. + +@quotation NOTA +Quando @`e stata specificata l'opzione @option{--sandbox} (@pxref{Opzioni}), +la lettura di input da file, @dfn{pipe} e coprocessi non @`e possibile. +@end quotation + +@menu +* Getline semplice:: Usare @code{getline} senza argomenti. +* Getline variabile:: Usare @code{getline} in una variabile. +* Getline file:: Usare @code{getline} da un file. +* Getline variabile file:: Usare @code{getline} in una variabile da un + file. +* Getline @dfn{pipe}:: Usare @code{getline} da una @dfn{pipe}. +* Getline variabile @dfn{pipe}:: Usare @code{getline} in una variabile da una + @dfn{pipe}. +* Getline coprocesso:: Usare @code{getline} da un coprocesso. +* Getline variabile coprocesso:: Usare @code{getline} in una variabile da un + coprocesso. +* Note su getline:: Cose importanti da sapere su @code{getline}. +* Sommario di getline:: Sommario delle varianti di @code{getline}. +@end menu + +@node Getline semplice +@subsection Usare @code{getline} senza argomenti + +Il comando @code{getline} pu@`o essere usato senza argomenti per leggere l'input +dal file in input corrente. Tutto quel che fa in questo caso @`e leggere il +record in input successivo e dividerlo in campi. Questo @`e utile se @`e +finita l'elaborarezione del record corrente, e si vogliono fare delle +elaborazioni particolari sul record successivo @emph{proprio adesso}. +Per esempio: + +@example +# rimuovere il testo tra /* e */, compresi +@{ + if ((i = index($0, "/*")) != 0) @{ + prima = substr($0, 1, i - 1) # la parte iniziale della stringa + dopo = substr($0, i + 2) # ... */ ... + j = index(dopo, "*/") # */ @`e nella parte finale? + if (j > 0) @{ + dopo = substr(dopo, j + 2) # rimozione del commento + @} else @{ + while (j == 0) @{ + # passa ai record seguenti + if (getline <= 0) @{ + print("Fine file inattesa o errore:", ERRNO) > "/dev/stderr" + exit + @} + # incrementare la riga usando la concatenazione di stringhe + dopo = dopo $0 + j = index(dopo, "*/") # @`e */ nella parte finale? + if (j != 0) @{ + dopo = substr(dopo, j + 2) + break + @} + @} + @} + # incrementare la riga di output usando la concatenazione + # di stringhe + $0 = prima dopo + @} + print $0 +@} +@end example + +@c 8/2014: Here is some sample input: +@ignore +mon/*comment*/key +rab/*commen +t*/bit +horse /*comment*/more text +part 1 /*comment*/part 2 /*comment*/part 3 +no comment +@end ignore + +Questo programma @command{awk} cancella i commenti in stile C +(@samp{/* @dots{} */}) dall'input. +Usa diverse funzionalit@`a che non sono ancora state trattate, incluse la +concatenazione di stringhe +(@pxref{Concatenazione}) +e le funzioni predefinite @code{index()} e @code{substr()} +(@pxref{Funzioni per stringhe}). +Sostituendo @samp{print $0} con altre +istruzioni, si possono effettuare elaborazioni pi@`u complesse sull'input +decommentato, come ricercare corrispondenze di un'espressione regolare. +(Questo programma ha un piccolo problema: non funziona se c'@`e pi@`u di un +commento che inizia e finisce +sulla stessa riga.) + +Questa forma del comando @code{getline} imposta @code{NF}, +@code{NR}, @code{FNR}, @code{RT} e il valore di @code{$0}. + +@quotation NOTA +Il nuovo valore di @code{$0} @`e usato per verificare +le espressioni di ricerca di ogni regola successiva. Il valore originale +di @code{$0} che ha attivato la regola che ha eseguito la @code{getline} +viene perso. +A differenza di @code{getline}, l'istruzione @code{next} legge un nuovo record +ma inizia a elaborarlo normalmente, a partire dalla prima +regola presente nel programma. @xref{Istruzione next}. +@end quotation + +@node Getline variabile +@subsection Usare @code{getline} in una variabile +@cindex @code{getline} in una variabile +@cindex variabili, usare in comando @code{getline} + +Si pu@`o usare @samp{getline @var{var}} per leggere il record successivo +in input ad @command{awk} nella variabile @var{var}. Non vien fatta +nessun'altra elaborazione. +Per esempio, supponiamo che la riga successiva sia un commento o una stringa +particolare, e la si voglia leggere senza innescare nessuna regola. Questa +forma di @code{getline} permette di leggere quella riga e memorizzarla in una +variabile in modo che il ciclo principale di @command{awk} che "legge una riga +e controlla ogni regola" non la veda affatto. +L'esempio seguente inverte tra loro a due a due le righe in input: + +@example +@{ + if ((getline tmp) > 0) @{ + print tmp + print $0 + @} else + print $0 +@} +@end example + +@noindent +Prende la seguente lista: + +@example +wan +tew +free +phore +@end example + +@noindent +e produce questo risultato: + +@example +tew +wan +phore +free +@end example + +Il comando @code{getline} usato in questo modo imposta solo le variabili +@code{NR}, @code{FNR} e @code{RT} (e, naturalmente, @var{var}). +Il record non viene +suddiviso in campi, e quindi i valori dei campi (compreso @code{$0}) e +il valore di @code{NF} non cambiano. + +@node Getline file +@subsection Usare @code{getline} da un file + +@cindex @code{getline} da un file +@cindex input, ridirezione dell' +@cindex ridirezione dell'input +@cindex @code{<} (parentesi acuta sinistra), operatore @code{<} (I/O) +@cindex parentesi acuta sinistra (@code{<}), operatore @code{<} (I/O) +@cindex operatori di input/output +Si usa @samp{getline < @var{file}} per leggere il record successivo da +@var{file}. Qui, @var{file} @`e un'espressione di tipo stringa che +specifica il @value{FN}. @samp{< @var{file}} @`e una cosidetta +@dfn{ridirezione} perch@'e richiede che l'input provenga da un posto +differente. Per esempio, il seguente programma +legge il suo record in input dal file @file{secondary.input} quando +trova un primo campo con un valore uguale a 10 nel file in input +corrente: + +@example +@{ + if ($1 == 10) @{ + getline < "secondary.input" + print + @} else + print +@} +@end example + +Poich@'e non viene usato il flusso principale di input, i valori di @code{NR} e +@code{FNR} restano immutati. Comunque, il record in input viene diviso in +modo normale, per cui vengono cambiati i valori di @code{$0} e degli altri +campi, producendo un nuovo valore di @code{NF}. +Viene impostato anche @code{RT}. + +@cindex POSIX @command{awk}, operatore @code{<} e +@c Thanks to Paul Eggert for initial wording here +Per lo standard POSIX, @samp{getline < @var{espressione}} @`e ambiguo se +@var{espressione} contiene operatori che non sono all'interno di parentesi, +ad esclusione di @samp{$}; per esempio, @samp{getline < dir "/" file} @`e +ambiguo perch@'e l'operatore di concatenazione (non ancora trattato; +@pxref{Concatenazione}) non @`e posto tra parentesi. +Si dovrebbe scrivere invece @samp{getline < (dir "/" file)}, se il +programma dev'essere portabile su tutte le implementazioni di @command{awk}. + +@node Getline variabile file +@subsection Usare @code{getline} in una variabile da un file +@cindex variabili, usare in comando @code{getline} + +Si usa @samp{getline @var{var} < @var{file}} per leggere l'input +dal file +@var{file}, e metterlo nella variabile @var{var}. Come prima, @var{file} +@`e un'espressione di tipo stringa che specifica il file dal quale +legggere. + +In questa versione di @code{getline}, nessuna delle variabili predefinite @`e +cambiata e il record non @`e diviso in campi. La sola variabile cambiata @`e +@var{var}.@footnote{Questo non @`e completamente vero. @code{RT} pu@`o essere +cambiato se @code{RS} @`e un'espressione regolare.} +Per esempio, il seguente programma copia tutti i file in input nell'output, ad +eccezione dei record che dicono @w{@samp{@@include @var{nomefile}}}. +Tale record @`e sostituito dal contenuto del file +@var{nomefile}: + +@example +@{ + if (NF == 2 && $1 == "@@include") @{ + while ((getline line < $2) > 0) + print line + close($2) + @} else + print +@} +@end example + +Si noti come il nome del file in input aggiuntivo non compaia all'interno del +programma; @`e preso direttamente dai dati, e precisamente dal secondo campo +della riga di @code{@@include}. + +La funzione @code{close()} viene chiamata per assicurarsi che se nell'input +appaiono due righe @code{@@include} identiche, l'intero file specificato sia +incluso ogni volta. +@xref{Chiusura file e @dfn{pipe}}. + +Una carenza di questo programma @`e che non gestisce istruzioni +@code{@@include} nidificate +(cio@`e, istruzioni @code{@@include} contenute nei file inclusi) +nel modo in cui ci si aspetta che funzioni un vero preelaboratore di macro. +@xref{Programma igawk} per un programma +che gestisce le istruzioni @code{@@include} nidificate. + +@node Getline @dfn{pipe} +@subsection Usare @code{getline} da una @dfn{pipe} + +@c From private email, dated October 2, 1988. Used by permission, March 2013. +@cindex Kernighan, Brian +@quotation +@i{L'onniscienza ha molti aspetti positivi. +Se non si pu@`o ottenerla, l'attenzione ai dettagli pu@`o aiutare.} +@author Brian Kernighan +@end quotation + +@cindex @code{|} (barra verticale), operatore @code{|} (I/O) +@cindex barra verticale (@code{|}), operatore @code{|} (I/O) +@cindex input, @dfn{pipeline} +@cindex @dfn{pipe}, input +@cindex operatori, input/output +L'output di un comando pu@`o anche essere convogliato in @code{getline}, usando +@samp{@var{comando} | getline}. In +questo caso, la stringa @var{comando} viene eseguita come comando di shell e +il suo output @`e passato ad @command{awk} per essere usato come input. +Questa forma di @code{getline} legge un record alla volta dalla @dfn{pipe}. +Per esempio, il seguente programma copia il suo input nel suo output, +ad eccezione delle righe che iniziano con @samp{@@execute}, che sono +sostituite dall'output prodotto dall'esecuzione del resto della riga +costituito da un comando di shell. + +@example +@{ + if ($1 == "@@execute") @{ + tmp = substr($0, 10) # Rimuove "@@execute" + while ((tmp | getline) > 0) + print + close(tmp) + @} else + print +@} +@end example + +@noindent +La funzione @code{close()} viene chiamata per assicurarsi che, se appaiono +nell'input due righe @samp{@@execute} identiche, il comando sia eseguito per +ciascuna di esse. +@ifnottex +@ifnotdocbook +@xref{Chiusura file e @dfn{pipe}}. +@end ifnotdocbook +@end ifnottex +@c This example is unrealistic, since you could just use system +Dato l'input: + +@example +pippo +pluto +paperino +@@execute who +gastone +@end example + +@noindent +il programma potrebbe produrre: + +@cindex Robbins, Bill +@cindex Robbins, Miriam +@cindex Robbins, Arnold +@example +pippo +pluto +paperino +arnold ttyv0 Jul 13 14:22 +miriam ttyp0 Jul 13 14:23 (murphy:0) +bill ttyp1 Jul 13 14:23 (murphy:0) +gastone +@end example + +@noindent +Si osservi che questo programma ha eseguito @command{who} e stampato il +risultato. (Eseguendo questo programma, @`e chiaro che ciascun utente otterr@`a +risultati diversi, a seconda di chi @`e collegato al sistema.) + +Questa variante di @code{getline} divide il record in campi, imposta il valore +di @code{NF}, e ricalcola il valore di @code{$0}. I valori di +@code{NR} e @code{FNR} non vengono cambiati. +Viene impostato @code{RT}. + +@cindex POSIX @command{awk}, operatore I/O @code{|} e +@c Thanks to Paul Eggert for initial wording here +Per lo standard POSIX, @samp{@var{espressione} | getline} @`e ambiguo se +@var{espressione} contiene operatori che non sono all'interno di parentesi, +ad esclusione di @samp{$}. Per esempio, +@samp{@w{"echo "} "date" | getline} @`e ambiguo perch@'e +l'operatore di concatenazione non @`e tra parentesi. Si dovrebbe scrivere +invece @samp{(@w{"echo "} "date") | getline}, se il programma dev'essere +portabile su tutte le implementazioni di @command{awk}. + +@cindex Brian Kernighan, @command{awk} di +@cindex @command{mawk}, programma di utilit@`a +@cindex programma di utilit@`a @command{mawk} +@quotation NOTA +Sfortunatamente, @command{gawk} non ha un comportamento uniforme nel +trattare un costrutto come @samp{@w{"echo "} "date" | getline}. +La maggior parte delle versioni, compresa la versione corrente, lo tratta +come @samp{@w{("echo "} "date") | getline}. +(Questo @`e anche il comportamento di BWK @command{awk}.) +Alcune versioni invece lo trattano come +@samp{@w{"echo "} ("date" | getline)}. +(Questo @`e il comportamento di @command{mawk}.) +In breve, per evitare problemi, @`e @emph{sempre} meglio usare parentesi +esplicite. +@end quotation + +@node Getline variabile @dfn{pipe} +@subsection Usare @code{getline} in una variabile da una @dfn{pipe} +@cindex variabili, usare in comando @code{getline} + +Quando si usa @samp{@var{comando} | getline @var{var}}, +l'output di @var{comando} @`e inviato tramite una @dfn{pipe} a +@code{getline} ad una variabile @var{var}. Per esempio, il +seguente programma legge la data e l'ora corrente nella variabile +@code{current_time}, usando il programma di utilit@`a @command{date}, e poi lo +stampa: + +@example +BEGIN @{ + "date" | getline current_time + close("date") + print "Report printed on " current_time +@} +@end example + +In questa versione di @code{getline}, nessuna delle variabili predefinite @`e +cambiata e il record non @`e diviso in campi. In ogni caso, @code{RT} viene +impostato. + +@ifinfo +@c Thanks to Paul Eggert for initial wording here +Per lo standard POSIX, @samp{@var{espressione} | getline @var{var}} @`e ambiguo +se @var{espressione} contiene operatori che non sono all'interno di parentesi +ad esclusione di @samp{$}; per esempio, +@samp{@w{"echo "} "date" | getline @var{var}} @`e ambiguo +perch@'e l'operatore di concatenazione non @`e tra parentesi. Si dovrebbe +scrivere invece @samp{(@w{"echo "} "date") | getline @var{var}} se il +programma dev'essere portabile su tutte le implementazioni di @command{awk}. +@end ifinfo + +@node Getline coprocesso +@subsection Usare @code{getline} da un coprocesso +@cindex coprocessi, @code{getline} da +@cindex @code{getline}, comando, coprocessi@comma{} usare dal +@cindex @code{|} (barra verticale), operatore @code{|&} (I/O) +@cindex barra verticale (@code{|}), operatore @code{|&} (I/O) +@cindex operatori, input/output +@cindex differenze tra @command{awk} e @command{gawk}, operatori di input/output + +Leggere dell'input in @code{getline} da una @dfn{pipe} @`e un'operazione +unidirezionale. +Il comando avviato con @samp{@var{comando} | getline} invia dati +@emph{al} programma @command{awk}. + +Occasionalmente, si potrebbe avere la necessit@`a di inviare dei dati a un altro +programma che li elabori, per poi leggere il risultato che esso genera. +@command{gawk} permette di avviare un @dfn{coprocesso}, col quale sono +possibili comunicazioni bidirezionali. Questo vien fatto con l'operatore +@samp{|&}. +Tipicamente, dapprima si inviano dati al coprocesso e poi si leggono +i risultati da esso prodotto, come mostrato di seguito: + +@example +print "@var{some query}" |& "db_server" +"db_server" |& getline +@end example + +@noindent +esso invia una richiesta a @command{db_server} e poi legge i risultati. + +I valori di @code{NR} e +@code{FNR} non vengono cambiati, +perch@'e non @`e cambiato il flusso principale. +In ogni caso, il record @`e diviso in campi +nel solito modo, cambiando cos@`{@dotless{i}} i valori di @code{$0}, degli altri campi, +e di @code{NF} e @code{RT}. + +I coprocessi sono una funzionalit@`a avanzata. Vengono trattati qui solo perch@'e +@ifnotinfo +questa @`e la +@end ifnotinfo +@ifinfo +questo @`e il +@end ifinfo +@value{SECTION} su @code{getline}. +@xref{I/O bidirezionale}, +dove i coprocessi vengono trattati pi@`u dettagliatamente. + +@node Getline variabile coprocesso +@subsection Usare @code{getline} in una variabile da un coprocesso +@cindex variabili, usare in comando @code{getline} + +Quando si usa @samp{@var{comando} |& getline @var{var}}, l'output dal +coprocesso @var{comando} viene inviato tramite una @dfn{pipe} bidirezionale a +@code{getline} e nella variabile @var{var}. + +In questa versione di @code{getline}, nessuna delle variabili predefinite +viene cambiata e il record non viene diviso in campi. La sola variabile che +cambia @`e @var{var}. +In ogni caso, @code{RT} viene impostato. + +@ifinfo +I coprocessi sono una funzionalit@`a avanzata. Vengono trattati qui solo perch@'e +questo @`e il @value{SECTION} su @code{getline}. +@xref{I/O bidirezionale}, +dove i coprocessi vengono trattati pi@`u dettagliatamente. +@end ifinfo + +@node Note su getline +@subsection Cose importanti da sapere riguardo a @code{getline} +Qui sono elencate diverse considerazioni su @code{getline} +da tener presenti: + +@itemize @value{BULLET} +@item +Quando @code{getline} cambia il valore di @code{$0} e @code{NF}, +@command{awk} @emph{non} salta automaticamente all'inizio del +programma per iniziare a provare il nuovo record su ogni criterio di ricerca. +Comunque, il nuovo record viene provato su ogni regola successiva. + +@cindex differenze tra @command{awk} e @command{gawk}, limitazioni di implementazione +@cindex implementazione, problemi, @command{gawk}, limiti +@cindex @command{awk}, implementazioni, limiti +@cindex @command{gawk}, problemi di implementazioni, limiti +@item +Alcune tra le prime implementazioni di @command{awk} limitano a una sola il +numero di @dfn{pipeline} che un programma @command{awk} pu@`o tenere aperte. +In @command{gawk}, non c'@`e questo limite. +Si possono aprire tante @dfn{pipeline} (e coprocessi) quante ne permette il +sistema operativo in uso. + +@cindex effetti collaterali, variabile @code{FILENAME} +@cindex @code{FILENAME}, variabile, impostare con @code{getline} +@cindex angolo buio, variabile @code{FILENAME} +@cindex @code{getline}, comando, variabile @code{FILENAME} e +@cindex @code{BEGIN}, criterio di ricerca, @code{getline} e +@item +Un interessante effetto collaterale si ha se si usa @code{getline}, senza +una ridirezione, all'interno di una regola @code{BEGIN}. Poich@'e una +@code{getline} non ridiretta legge dai @value{DF} specificati nella riga di +comando, il primo comando @code{getline} fa s@`{@dotless{i}} che @command{awk} imposti +il valore di @code{FILENAME}. Normalmente, @code{FILENAME} non ha ancora un +valore all'interno delle regole @code{BEGIN}, perch@'e non si @`e ancora +iniziato a elaborare il +@value{DF} della riga di comando. +@value{DARKCORNER} +(Si veda @ref{BEGIN/END}; +e @pxref{Variabili auto-assegnate}.) + +@item +Usare @code{FILENAME} con @code{getline} +(@samp{getline < FILENAME}) +pu@`o essere fonte di +confusione. @command{awk} apre un flusso separato di input, diverso dal +file in input corrente. Comunque, poich@'e non si usa una variabile, +@code{$0} e @code{NF} vengono aggiornati. Se si sta facendo questo, @`e +probabilmente per sbaglio, e si dovrebbe rivedere quello che si sta cercando +di fare. + +@item +@ifdocbook +La prossima @value{SECTION} +@end ifdocbook +@ifnotdocbook +@ref{Sommario di getline}, +@end ifnotdocbook +contiene una tabella che sintetizza le +varianti di @code{getline} e le variabili da esse modificate. +@`E degno di nota che le varianti che non usano la ridirezione +possono far s@`{@dotless{i}} che @code{FILENAME} venga aggiornato se chiedono ad +@command{awk} di iniziare a leggere un nuovo file in input. + +@item +@cindex Moore, Duncan +Se la variabile assegnata @`e un'espressione con effetti collaterali, versioni +differenti di @command{awk} si comportano in modo diverso quando trovano la +fine-del-file [EOF]. Alcune versioni non valutano l'espressione; molte +versioni (compreso @command{gawk}) lo fanno. Si veda un esempio, gentilmente +fornito da Duncan Moore: + +@ignore +Date: Sun, 01 Apr 2012 11:49:33 +0100 +From: Duncan Moore <duncan.moore@@gmx.com> +@end ignore + +@example +BEGIN @{ + system("echo 1 > f") + while ((getline a[++c] < "f") > 0) @{ @} + print c +@} +@end example + +@noindent +Qui l'effetto secondario @`e @samp{++c}. Se viene trovata la fine del file +@emph{prima} di assegnare l'elemento @code{a}, @code{c} @`e incrementato o no? + +@command{gawk} tratta @code{getline} come una chiamata di funzione, e valuta +l'espressione @samp{a[++c]} prima di cercare di leggere da @file{f}. +Comunque, alcune versioni di @command{awk} valutano l'espressione solo +se c'@`e un valore di stringa da assegnare. +@end itemize + +@node Sommario di getline +@subsection Sommario delle varianti di @code{getline} +@cindex @code{getline}, comando, varianti + +La @ref{tabella-varianti-getline} +riassume le otto varianti di @code{getline}, +elencando le variabili predefinite che sono impostate da ciascuna di esse, +e se la variante @`e standard o @`e un'estensione di @command{gawk}. +Nota: per ogni variante, @command{gawk} imposta la variabile predefinita +@code{RT}. + +@float Tabella,tabella-varianti-getline +@caption{Varianti di @code{getline} e variabili impostate da ognuna} +@multitable @columnfractions .33 .38 .27 +@headitem Variante @tab Effetto @tab @command{awk} / @command{gawk} +@item @code{getline} @tab Imposta @code{$0}, @code{NF}, @code{FNR}, @code{NR}, e @code{RT} @tab @command{awk} +@item @code{getline} @var{var} @tab Imposta @var{var}, @code{FNR}, @code{NR}, e @code{RT} @tab @command{awk} +@item @code{getline <} @var{file} @tab Imposta @code{$0}, @code{NF}, e @code{RT} @tab @command{awk} +@item @code{getline @var{var} < @var{file}} @tab Imposta @var{var} e @code{RT} @tab @command{awk} +@item @var{comando} @code{| getline} @tab Imposta @code{$0}, @code{NF}, e @code{RT} @tab @command{awk} +@item @var{comando} @code{| getline} @var{var} @tab Imposta @var{var} e @code{RT} @tab @command{awk} +@item @var{comando} @code{|& getline} @tab Imposta @code{$0}, @code{NF}, e @code{RT} @tab @command{gawk} +@item @var{comando} @code{|& getline} @var{var} @tab Imposta @var{var} e @code{RT} @tab @command{gawk} +@end multitable +@end float + +@node Timeout in lettura +@section Leggere input entro un tempo limite +@cindex tempo limite, leggere input +@cindex @dfn{timeout}, si veda tempo limite + +@cindex differenze tra @command{awk} e @command{gawk}, tempo limite per lettura +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} descrive una funzionalit@`a disponibile solo in +@command{gawk}. + +Si pu@`o specificare un tempo limite in millisecondi per leggere l'input dalla +tastiera, da una @dfn{pipe} o da una comunicazione bidirezionale, compresi i +@dfn{socket} TCP/IP. Questo pu@`o essere fatto per input, per comando o per +connessione, impostando un elemento speciale nel vettore @code{PROCINFO} +(@pxref{Variabili auto-assegnate}): + +@example +PROCINFO["nome_input", "READ_TIMEOUT"] = @var{tempo limite in millisecondi} +@end example + +Se @`e impostato, @command{gawk} smette di attendere una risposta e restituisce +insuccesso se non sono disponibili dati da leggere entro il limite di tempo +specificato. Per esempio, un cliente TCP pu@`o decidere di abbandonare se +non riceve alcuna risposta dal server dopo un certo periodo di tempo: + +@example +Service = "/inet/tcp/0/localhost/daytime" +PROCINFO[Service, "READ_TIMEOUT"] = 100 +if ((Service |& getline) > 0) + print $0 +else if (ERRNO != "") + print ERRNO +@end example + +Qui vediamo come ottenere dati interattivamente dall'utente@footnote{Questo +presuppone che lo standard input provenga dalla tastiera.} aspettando per +non pi@`u di cinque secondi: + +@example +PROCINFO["/dev/stdin", "READ_TIMEOUT"] = 5000 +while ((getline < "/dev/stdin") > 0) + print $0 +@end example + +@command{gawk} termina l'operazione di lettura se l'input non +arriva entro il periodo di tempo limite, restituisce insuccesso +e imposta @code{ERRNO} a una stringa di valore adeguato. +Un valore del tempo limite negativo o pari a zero equivale a non specificare +affatto un tempo limite. + +Si pu@`o impostare un tempo limite anche per leggere dalla tastiera nel ciclo +implicito che legge i record in input e li confronta coi criteri di ricerca, +come: + +@example +$ @kbd{gawk 'BEGIN @{ PROCINFO["-", "READ_TIMEOUT"] = 5000 @}} +> @kbd{@{ print "You entered: " $0 @}'} +@kbd{gawk} +@print{} You entered: gawk +@end example + +In questo caso, la mancata risposta entro cinque secondi d@`a luogo al seguente +messaggio di errore: + +@example +@c questo @`e l'output effettivo - Antonio +@error{} gawk: linea com.:2: (FILENAME=- FNR=1) fatale: errore leggendo +@error{} file in input `-': Connessione scaduta +@end example + +Il tempo limite pu@`o essere impostato o cambiato in qualsiasi momento, e avr@`a +effetto al tentativo successivo di leggere dal dispositivo di input. Nel +seguente esempio, partiamo con un valore di tempo limite di un secondo e +lo riduciamo progressivamente di un decimo di secondo finch@'e l'attesa +per l'input diventa illimitata. + +@example +PROCINFO[Service, "READ_TIMEOUT"] = 1000 +while ((Service |& getline) > 0) @{ + print $0 + PROCINFO[Service, "READ_TIMEOUT"] -= 100 +@} +@end example + +@quotation NOTA +Non si deve dare per scontato che l'operazione di lettura si blocchi +esattamente dopo che @`e stato stampato il decimo record. @`E possibile che +@command{gawk} legga e tenga in memoria i dati di pi@`u di un record +la prima volta. Per questo, cambiare il valore del tempo +limite come nell'esempio appena visto non @`e molto utile. +@end quotation + +Se l'elemento di @code{PROCINFO} non @`e presente e la variabile d'ambiente +@env{GAWK_READ_TIMEOUT} esiste, +@command{gawk} usa il suo valore per inizializzare il valore di tempo limite. +L'uso esclusivo della variabile d'ambiente per specificare il tempo limite +ha lo svantaggio di non essere +adattabile per ogni comando o per ogni connessione. + +@command{gawk} considera errore un superamento di tempo limite anche se +il tentativo di leggere dal dispositivo sottostante potrebbe riuscire +in un tentativo successivo. Questa @`e una limitazione, e inoltre +significa che non @`e possibile usarlo per ottenere input multipli, +provenienti da due o pi@`u sorgenti. @xref{Proseguire dopo errore in input} +per una modalit@`a che consente di tentare ulteriori operazioni di I/O. + +Assegnare un valore di tempo limite previene un blocco a tempo indeterminato +legato a operazioni di lettura. Si tenga per@`o presente che ci sono altre +situazioni in cui @command{gawk} pu@`o restare bloccato in attesa che un +dispositivo di input sia pronto. Un cliente di rete a volte pu@`o impiegare +molto tempo per stabilire una +connessione prima di poter iniziare a leggere qualsiasi dato, +oppure il tentativo di aprire un file speciale FIFO in lettura pu@`o bloccarsi +indefinitamente in attesa che qualche altro processo lo apra in scrittura. + +@node Proseguire dopo errore in input +@section Elaborare ulteriore input dopo certi errori di I/O +@cindex proseguire dopo errore in input +@cindex errore in input, possibilit@`a di proseguire + +@cindex differenze tra @command{awk} e @command{gawk}, proseguire dopo errore in input +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} descrive una funzionalit@`a disponibile solo in +@command{gawk}. + +Qualora @command{gawk} incontri un errore durante la lettura dell'input, +per default @code{getline} ha come codice di ritorno @minus{}1, e i +successivi tentativi di leggere dallo stesso file restituiscono una +indicazione di fine-file. @`E tuttavia possibile chiedere a +@command{gawk} di consentire un ulteriore tentativo di lettura in presenza +di certi errori, impostando uno speciale elemento del vettore +@code{PROCINFO} (@pxref{Variabili auto-assegnate}): + +@example +PROCINFO["@var{nome_input_file}", "RETRY"] = 1 +@end example + +Quando un tale elemento esiste, @command{gawk} controlla il valore della +variabile di sistema +(nel linguaggio C) +@code{errno} quando si verifica un errore di I/O. +Se @code{errno} indica che un ulteriore tentativo di lettura pu@`o +terminare con successo, @code{getline} ha come codice di ritorno @minus{}2 +e ulteriori chiamate a @code{getline} possono terminare correttamente. +Questo vale per i seguenti valori di @code{errno}: @code{EAGAIN}, +@code{EWOULDBLOCK}, @code{EINTR}, e @code{ETIMEDOUT}. + +Questa funzionalit@`a @`e utile quando si assegna un valore all'elemento +@code{PROCINFO["@var{nome_input_file}", "READ_TIMEOUT"]} o in situazioni +in cui un descrittore di file sia stato configurato per comportarsi in +modo non bloccante. + +@node Directory su riga di comando +@section Directory sulla riga di comando +@cindex differenze tra @command{awk} e @command{gawk}, directory sulla riga di comando +@cindex directory, riga di comando +@cindex riga di comando, directory su + +Per lo standard POSIX, i file che compaiono sulla riga di comando di +@command{awk} devono essere file di testo; @`e un errore fatale se non lo sono. +La maggior parte delle versioni di @command{awk} genera un errore fatale +quando trova una directory sulla riga di comando. + +Per default, @command{gawk} emette un avvertimento se c'@`e una directory sulla +riga di comando, e in ogni caso la ignora. Questo rende pi@`u facile usare +metacaratteri di shell col proprio programma @command{awk}: + +@example +$ @kbd{gawk -f whizprog.awk *} @ii{Le directory potrebbero far fallire il programma} +@end example + +Se viene data una delle opzioni @option{--posix} +o @option{--traditional}, @command{gawk} considera invece +una directory sulla riga di comando come un errore fatale. + +@xref{Esempio di estensione Readdir} per un modo di trattare le directory +come dati usabili da un programma @command{awk}. + +@sp 2 +@node Sommario di Input +@section Sommario di Input + +@itemize @value{BULLET} +@item +L'input @`e diviso in record in base al valore di @code{RS}. +Le possibilit@`a sono le seguenti: + +@multitable @columnfractions .28 .45 .40 +@headitem Valore di @code{RS} @tab Record separati da @dots{} @tab @command{awk} / @command{gawk} +@item Un carattere singolo @tab Quel carattere @tab @command{awk} +@item La stringa nulla (@code{""}) @tab Serie di due o pi@`u ritorni a capo @tab @command{awk} +@item Un'espressione regolare @tab Testo corrispondente alla @dfn{regexp} @tab @command{gawk} +@end multitable + +@item +@code{FNR} indica quanti record sono stati letti dal file in input corrente; +@code{NR} indica quanti record sono stati letti in totale. + +@item +@command{gawk} imposta @code{RT} al testo individuato da @code{RS}. + +@item +Dopo la divisione dell'input in record, @command{awk} divide +i record in singoli campi, chiamati @code{$1}, @code{$2} e cos@`{@dotless{i}} +via. @code{$0} @`e l'intero record, e @code{NF} indica quanti campi +contiene. Il metodo di default per dividere i campi utilizza i +caratteri di spazio vuoto. + +@item Si pu@`o far riferimento ai campi usando una variabile, come in @code{$NF}. +Ai campi possono anche essere assegnati dei valori, e questo implica che il +valore di @code{$0} sia ricalcolato se ad esso si fa riferimento in seguito. +Fare un assegnamento a un campo con un numero maggiore di @code{NF} crea il +campo e ricostruisce il record, usando @code{OFS} per separare i campi. +Incrementare @code{NF} fa la stessa cosa. Decrementare @code{NF} scarta dei +campi e ricostruisce il record. + +@item +Separare i campi @`e pi@`u complicato che separare i record. + +@multitable @columnfractions .40 .40 .20 +@headitem Valore del separatore di campo @tab Campi separati @dots{} @tab @command{awk} / @command{gawk} +@item @code{FS == " "} @tab Da serie di spazi vuoti @tab @command{awk} +@item @code{FS == @var{un solo carattere}} @tab Da quel carattere @tab @command{awk} +@item @code{FS == @var{espr. reg.}} @tab Dal testo che corrisponde alla @dfn{regexp} @tab @command{awk} +@item @code{FS == ""} @tab Cos@`{@dotless{i}} ogni singolo carattere @`e un campo separato @tab @command{gawk} +@item @code{FIELDWIDTHS == @var{lista di colonne}} @tab Basata sulla posizione del carattere @tab @command{gawk} +@item @code{FPAT == @var{regexp}} @tab Dal testo attorno al testo corrispondente alla @dfn{regexp} @tab @command{gawk} +@end multitable + +@item +Usando @samp{FS = "\n"} l'intero record sar@`a un unico campo +(nell'ipotesi che i record siano separati da caratteri di ritorno a capo). + +@item +@code{FS} pu@`o essere impostato dalla riga di comando con l'opzione +@option{-F}. +Si pu@`o fare la stessa cosa usando un assegnamento di variabile da riga di +comando. + +@item +@code{PROCINFO["FS"]} permette di sapere come i campi sono separati. + +@item +@code{getline} nelle sue diverse forme serve per leggere record aggiuntivi +provenienti dal flusso di input di default, da un file, o da una @dfn{pipe} +o da un coprocesso. + +@item +@code{PROCINFO[@var{file}, "READ_TIMEOUT"]} si pu@`o usare per impostare un +tempo limite alle operazioni di lettura da @var{file}. + +@item +Le directory sulla riga di comando generano un errore fatale per +@command{awk} standard; +@command{gawk} le ignora se non @`e in modalit@`a POSIX. + +@end itemize + +@c EXCLUDE START +@node Esercizi su Input +@section Esercizi + +@enumerate +@item +Usando la variabile @code{FIELDWIDTHS} (@pxref{Dimensione costante}), +scrivere un programma per leggere i dati delle elezioni, dove ogni record +rappresenta i voti di un votante. Trovare un modo per definire quali colonne +sono associate a ogni quesito elettorale, e stampare i voti totali, +comprese le astensioni, per ciascun quesito. +@item +La @ref{Getline semplice}, ha illustrato un programma per rimuovere i commenti +in stile C (@samp{/* @dots{} */}) dall'input. Quel programma +non funziona se un commento termina in una riga e il successivo commento +inizia nella stessa riga. +Il problema si pu@`o risolvere con una semplice modifica. Quale? + +@end enumerate +@c EXCLUDE END + +@node Stampare +@chapter Stampare in output + +@cindex stampare +@cindex output, stampare, si veda stampare +Una delle azioni che un programma fa pi@`u comunemente, @`e quella di produrre +@dfn{stampe}, ossia scrivere in output l'input letto, tutto o in parte. +Si pu@`o usare l'istruzione @code{print} per una stampa semplice, e l'istruzione +@code{printf} per una formattazione dell'output pi@`u sofisticata. +L'istruzione @code{print} non ha un limite al numero di elementi quando +calcola @emph{quali} valori stampare. Peraltro, con due eccezioni, +non @`e possibile specificare @emph{come} stamparli: quante +colonne, se usare una notazione esponenziale o no, etc. +(Per le eccezioni, @pxref{Separatori di output} e +la @ref{OFMT}.) +Per stampare fornendo delle specifiche, @`e necessario usare +l'istruzione @code{printf} +(@pxref{Printf}). + +@cindex istruzione @code{print} +@cindex istruzione @code{printf} +Oltre alla stampa semplice e formattata, questo @value{CHAPTER} +esamina anche le ridirezioni di I/O verso file e @dfn{pipe}, introduce +i @value{FNS} speciali che @command{gawk} elabora internamente, +e parla della funzione predefinita @code{close()}. + +@menu +* Print:: L'istruzione @code{print}. +* Esempi su print:: Semplici esempi di + istruzioni @code{print}. +* Separatori di output:: I separatori di output e come + modificarli. +* OFMT:: Controllare l'output di numeri con + @code{print}. +* Printf:: l'istruzione @code{printf}. +* Ridirezione:: Come ridirigere l'output a diversi + file e @dfn{pipe}. +* FD speciali:: I/O con FD [Descrittori File] + speciali. +* File speciali:: Interpretazione nomi file in + @command{gawk}. @command{gawk} + Permette di accedere a descrittori + file gi@`a aperti a inizio esecuzione +* Chiusura file e @dfn{pipe}:: Chiudere file in input e di output e + @dfn{pipe}. +* Continuazione dopo errori:: Abilitare continuazione dopo errori + in output. +* Sommario di Output:: Sommario di Output. +* Esercizi su Output:: Esercizi. +@end menu + +@node Print +@section L'istruzione @code{print} + +L'istruzione @code{print} si usa per produrre dell'output formattato in +maniera semplice, standardizzata. Si +specificano solo le stringhe o i numeri +da stampare, in una lista separata da virgole. Questi elementi sono stampati, +separati tra loro da spazi singoli, e alla fine viene stampato un ritorno a +capo. L'istruzione @`e simile a questa: + +@example +print @var{elemento1}, @var{elemento2}, @dots{} +@end example + +@noindent +L'intera lista di elementi pu@`o facoltativamente essere racchiusa fra +parentesi. Le parentesi sono obbligatorie se qualche espressione presente +in uno degli elementi usa l'operatore relazionale @samp{>}, che potrebbe +essere confuso con una ridirezione dell'output (@pxref{Ridirezione}). + +Gli elementi da stampare possono essere stringhe costanti o numeri, campi +del record corrente (come @code{$1}), variabili, o quasiasi espressione +@command{awk}. I valori numerici sono convertiti in stringhe prima di essere +stampati. + +@cindex record, stampare +@cindex righe, vuote, stampare +@cindex testo, stampare +Una semplice istruzione @samp{print} senza specificare elementi equivale a +@samp{print $0}: stampa l'intero record corrente. Per stampare una riga +vuota, si usa @samp{print ""}. +Per stampare un testo che non cambia, si usi come elemento una costante +stringa, per esempio @w{@code{"Non v'allarmate"}}. Dimenticandosi di mettere +i doppi apici, il testo @`e preso per un'espressione @command{awk}, +e probabilmente verr@`a emesso un messaggio di errore. Occorre tener presente +che tra ogni coppia di elementi viene stampato uno spazio. + +Si noti che l'istruzione @code{print} @`e un'istruzione, e non +un'espressione: non @`e possibile usarla nella parte modello [di ricerca] di +un'istruzione @dfn{criterio di ricerca--azione}, per esempio. + +@node Esempi su print +@section Esempi di istruzioni @code{print} + +Ogni istruzione @code{print} produce almeno una riga in output. Comunque, +non @`e limitata a una sola riga. Se il valore di un elemento @`e una stringa +che contiene un ritorno a capo, il ritorno a capo @`e stampato insieme al +resto della stringa. Una +singola istruzione @code{print} pu@`o in questo modo generare un numero +qualsiasi di righe. + +@cindex ritorno a capo, stampare un +Quel che segue @`e un esempio di stampa di una stringa che contiene al suo +interno dei +@ifinfo +ritorni a capo +(la @samp{\n} @`e una sequenza di protezione, che si usa per rappresentare il +carattere di ritorno a capo; @pxref{Sequenze di protezione}): +@end ifinfo +@ifhtml +ritorni a capo +(la @samp{\n} @`e una sequenza di protezione, che si usa per rappresentare il +carattere di ritorno a capo; @pxref{Sequenze di protezione}): +@end ifhtml +@ifnotinfo +@ifnothtml +ritorni a capo: +@end ifnothtml +@end ifnotinfo + +@example +$ @kbd{awk 'BEGIN @{ print "riga uno\nriga due\nriga tre" @}'} +@print{} riga uno +@print{} riga due +@print{} riga tre +@end example + +@cindex campi, stampare +Il prossimo esempio, eseguito sul file @file{inventory-shipped}, +stampa i primi due campi di ogni record in input, separandoli con uno +spazio: + +@example +$ @kbd{awk '@{ print $1, $2 @}' inventory-shipped} +@print{} Jan 13 +@print{} Feb 15 +@print{} Mar 15 +@dots{} +@end example + +@cindex istruzione @code{print}, virgole, omettere +@cindex debug, istruzione @code{print}@comma{} omissione virgole +Un errore frequente usando l'istruzione @code{print} @`e quello di tralasciare +la virgola tra due elementi. Questo ha spesso come risultato la stampa di +elementi attaccati tra loro, senza lo spazio di separazione. Il motivo per +cui ci@`o accade @`e che la scrittura di due +espressioni di stringa in @command{awk} ne indica la concatenazione. Qui si +vede l'effetto dello stesso programma, +senza le virgole: + +@example +$ @kbd{awk '@{ print $1 $2 @}' inventory-shipped} +@print{} Jan13 +@print{} Feb15 +@print{} Mar15 +@dots{} +@end example + +@cindex @code{BEGIN}, criterio di ricerca, intestazioni, aggiungere +Per chi non conosce il file @file{inventory-shipped} nessuno +dei due output di esempio risulta molto comprensibile. Una riga iniziale di +intestazione li renderebbe pi@`u chiari. +Aggiungiamo qualche intestazione alla nostra tabella dei mesi +(@code{$1}) e dei contenitori verdi spediti (@code{$2}). Lo facciamo usando +una regola @code{BEGIN} (@pxref{BEGIN/END}) in modo che le intestazioni siano +stampate una volta sola: + +@example +awk 'BEGIN @{ print "Mese Contenitori" + print "----- -----------" @} + @{ print $1, $2 @}' inventory-shipped +@end example + +@noindent +Una volta eseguito, il programma stampa questo: + +@example +Mese Contenitori +----- ----------- +Jan 13 +Feb 15 +Mar 15 +@dots{} +@end example + +@noindent +Il solo problema, in effetti, @`e che le intestazioni e i dati della tabella +non sono allineati! Possiamo provvedere stampando alcuni spazi tra i due +campi: + +@example +@group +awk 'BEGIN @{ print "Mese Contenitori" + print "----- -----------" @} + @{ print $1, " ", $2 @}' inventory-shipped +@end group +@end example + +@cindex istruzione @code{printf}, colonne@comma{} allineamento +@cindex colonne, allineamento +Allineare le colonne in questo modo pu@`o diventare piuttosto +complicato, quando ci sono parecchie colonne da tenere allineate. Contare gli +spazi per due o tre colonne @`e semplice, ma oltre questo limite comincia a +volerci molto tempo. Ecco perch@'e @`e disponibile l'istruzione @code{printf} +(@pxref{Printf}); +una delle possibilit@`a che offre @`e quella di allineare colonne di dati. + +@cindex continuazione di riga, in istruzione @code{print} +@cindex istruzione @code{print}, continuazione di riga e +@cindex @code{print}, istruzione, continuazione di riga e +@quotation NOTA +Si pu@`o continuare su pi@`u righe sia l'istruzione @code{print} che l'istruzione +@code{printf} semplicemente mettendo un ritorno a capo dopo una virgola +qualsiasi +(@pxref{Istruzioni/Righe}). +@end quotation + +@node Separatori di output +@section I separatori di output e come modificarli + +@cindex variabile @code{OFS} +Come detto sopra, un'istruzione @code{print} contiene una lista di elementi +separati da virgole. Nell'output, gli elementi sono solitamente separati +da spazi singoli. Non @`e detto tuttavia che debba sempre essere cos@`{@dotless{i}}; uno +spazio singolo @`e semplicemnte il valore di default. Qualsiasi stringa di +caratteri pu@`o essere usata come +@dfn{separatore di campo in output} impostando la variabile +predefinita @code{OFS}. Il valore iniziale di questa variabile @`e +la stringa @w{@code{" "}} (cio@`e, uno spazio singolo). + +L'output di un'istruzione @code{print} completa @`e detto un @dfn{record di +output}. Ogni istruzione @code{print} stampa un record di output, e alla fine +ci aggiunge una stringa detta @dfn{separatore record in output} (o +@code{ORS}). Il valore iniziale di @code{ORS} @`e la stringa @code{"\n"} +(cio@`e, un carattere di ritorno a capo). Quindi, ogni istruzione +@code{print} normalmente genera [almeno] una riga a s@'e stante. + +@cindex output, record +@cindex separatore di record in output, si veda @code{ORS}, variabile +@cindex @code{ORS}, variabile +@cindex @code{BEGIN}, criterio di ricerca, variabili @code{OFS}/@code{ORS}, assegnare valori a +Per cambiare il tipo di separazione in output di campi e record, si impostano +valori differenti alle variabili @code{OFS} e @code{ORS}. Il posto pi@`u +indicato per farlo @`e nella regola @code{BEGIN} +(@pxref{BEGIN/END}), in modo che l'assegnazione abbia effetto prima +dell'elaborazione di ogni record in input. Questi valori si possono +anche impostare dalla riga di comando, prima della lista dei file in input, +oppure usando l'opzione della riga di comando @option{-v} +(@pxref{Opzioni}). +L'esempio seguente stampa il primo e il secondo campo di ogni record in input, +separati da un punto e virgola, con una riga vuota aggiunta dopo ogni +ritorno a capo: + + +@example +$ @kbd{awk 'BEGIN @{ OFS = ";"; ORS = "\n\n" @}} +> @kbd{@{ print $1, $2 @}' mail-list} +@print{} Amelia;555-5553 +@print{} +@print{} Anthony;555-3412 +@print{} +@print{} Becky;555-7685 +@print{} +@print{} Bill;555-1675 +@print{} +@print{} Broderick;555-0542 +@print{} +@print{} Camilla;555-2912 +@print{} +@print{} Fabius;555-1234 +@print{} +@print{} Julie;555-6699 +@print{} +@print{} Martin;555-6480 +@print{} +@print{} Samuel;555-3430 +@print{} +@print{} Jean-Paul;555-2127 +@print{} +@end example + +Se il valore di @code{ORS} non contiene un ritorno a capo, l'output del +programma viene scritto tutto su un'unica riga. + +@node OFMT +@section Controllare l'output di numeri con @code{print} +@cindex numerico, formato di output +@cindex formati numerici di output +Quando si stampano valori numerici con l'istruzione @code{print}, +@command{awk} converte internamente ogni numero in una stringa di caratteri +e stampa quella stringa. @command{awk} usa la funzione @code{sprintf()} +per effettuare questa conversione +(@pxref{Funzioni per stringhe}). +Per ora, basta dire che la funzione @code{sprintf()} +accetta una @dfn{specifica di formato} che indica come formattare +i numeri (o le stringhe), e che ci sono svariati modi per formattare i +numeri. Le differenti specifiche di formato sono trattate pi@`u +esaurientemente +@iftex +nella +@end iftex +@ifnottex +in +@end ifnottex +@ref{Lettere di controllo}. + +@cindexawkfunc{sprintf} +@cindex @code{OFMT}, variabile +@cindex output, specificatore di formato@comma{} @code{OFMT} +La variabile predefinita @code{OFMT} contiene la specifica di formato +che @code{print} usa con @code{sprintf()} per convertire un numero in +una stringa per poterla stampare. +Il valore di default di @code{OFMT} @`e @code{"%.6g"}. +Il modo in cui @code{print} stampa i numeri si pu@`o cambiare +fornendo una specifica di formato differente +per il valore di @code{OFMT}, come mostrato nell'esempio seguente: + +@example +$ @kbd{awk 'BEGIN @{} +> @kbd{OFMT = "%.0f" # Stampa numeri come interi (arrotonda)} +> @kbd{print 17.23, 17.54 @}'} +@print{} 17 18 +@end example + +@noindent +@cindex angolo buio, variabile @code{OFMT} +@cindex POSIX @command{awk}, variabile @code{OFMT} e +@cindex variabile @code{OFMT}, POSIX @command{awk} e +Per lo standard POSIX, il comportamento di @command{awk} @`e indefinito +se @code{OFMT} contiene qualcosa di diverso da una specifica di conversione +di un numero a virgola mobile. +@value{DARKCORNER} + +@node Printf +@section Usare l'istruzione @code{printf} per stampe sofisticate + +@cindex istruzione @code{printf} +@cindex @code{printf}, istruzione +@cindex output, formattato +@cindex formattare l'output +Per un controllo pi@`u ampio sul formato di output di quello fornito da +@code{print}, si pu@`o usare @code{printf}. +Con @code{printf} si pu@`o +specificare lo spazio da utilizzare per ogni elemento, e anche le varie +scelte di formattazione disponibile per i numeri (come la base da usare in +output, se stampare con notazione esponenziale, se inserire un segno, e quante +cifre stampare dopo il separatore decimale). + +@menu +* Printf Fondamenti:: Sintassi dell'istruzione + @code{printf}. +* Lettere di controllo:: Lettere di controllo del formato. +* Modificatori di formato:: Modificatori specifiche di formato. +* Esempi su printf:: Numerosi esempi. +@end menu + +@node Printf Fondamenti +@subsection Sintassi dell'istruzione @code{printf} + +@cindex istruzione @code{printf}, sintassi dell' +@cindex @code{printf}, sintassi dell'istruzione +Una semplice istruzione @code{printf} @`e qualcosa di simile a questo: + +@example +printf @var{formato}, @var{elemento1}, @var{elemento2}, @dots{} +@end example + +@noindent +Come nel caso di @code{print}, l'intera lista degli argomenti pu@`o +facoltativamente essere racchiusa fra +parentesi. Anche qui, le parentesi sono obbligatorie se l'espressione di +qualche elemento usa l'operatore +relazionale @samp{>}, che potrebbe +essere confuso con una ridirezione dell'output (@pxref{Ridirezione}). + +@cindex specificatori di formato +La differenza tra @code{printf} e @code{print} @`e l'argomento @var{formato}. +Questo @`e un'espressione il cui valore @`e visto come una stringa; +specifica come scrivere in output ognuno degli altri argomenti. @`E chiamata +@dfn{stringa di formato}. + +La stringa di formato @`e molto simile a quella usata dalla funzione di +libreria ISO C @code{printf()}. Buona parte del @var{formato} @`e testo da +stampare cos@`{@dotless{i}} come @`e scritto. +All'interno di questo testo ci sono degli @dfn{specificatori di formato}, +uno per ogni elemento da stampare. +Ogni specificatore di formato richiede di stampare l'elemento successivo +nella lista degli argomenti +in quella posizione del formato. + +L'istruzione @code{printf} non aggiunge in automatico un ritorno a capo +al suo output. Scrive solo quanto specificato dalla stringa di formato. +Quindi, se serve un ritorno a capo, questo va incluso nella stringa di formato. +Le variabili di separazione dell'output @code{OFS} e @code{ORS} non hanno +effetto sulle istruzioni @code{printf}. +Per esempio: + +@example +$ @kbd{awk 'BEGIN @{} +> @kbd{ORS = "\nAHI!\n"; OFS = "+"} +> @kbd{msg = "Non v\47allarmate!"} +> @kbd{printf "%s\n", msg} +> @kbd{@}'} +@print{} Non v'allarmate! +@end example + +@noindent +Qui, n@'e il @samp{+} n@'e l'esclamazione @samp{AHI!} compaiono nel messaggio +in output. + +@node Lettere di controllo +@subsection Lettere di controllo del formato +@cindex istruzione @code{printf}, lettere di controllo del formato +@cindex @code{printf}, istruzione, lettere di controllo del formato +@cindex specificatori di formato, istruzione @code{printf} + +Uno specificatore di formato inizia col carattere @samp{%} e termina con +una @dfn{lettera di controllo del formato}; e dice all'istruzione +@code{printf} come stampare un elemento. La lettera di controllo del +formato specifica che @emph{tipo} +di valore stampare. Il resto dello specificatore di formato @`e costituito da +@dfn{modificatori} facoltativi che controllano @emph{come} stampare il valore, +per esempio stabilendo la larghezza del campo. Ecco una lista delle +lettere di controllo del formato: + +@c @asis for docbook to come out right +@table @asis +@item @code{%c} +Stampa un numero come un carattere; quindi, @samp{printf "%c", +65} stampa la lettera @samp{A}. L'output per un valore costituito da una +stringa @`e il primo carattere della stringa stessa. + +@cindex angolo buio, caratteri di controllo del formato +@cindex @command{gawk}, caratteri di controllo del formato +@quotation NOTA +Lo standard POSIX richiede che il primo carattere di una stringa sia stampato. +In localizzazioni con caratteri multibyte, @command{gawk} tenta di +convertire i primi byte della stringa in un carattere multibyte valido +e poi di stampare la codifica multibyte di quel carattere. +Analogamente, nella stampa di un valore numerico, @command{gawk} ammette che +il valore appartenga all'intervallo numerico di valori che possono essere +contenuti in un carattere multibyte. +Se la conversione alla codifica multibyte non riesce, @command{gawk} +usa gli ultimi otto bit della cifra (quelli meno significativi) come +carattere da stampare. + +Altre versioni di @command{awk} generalmente si limitano a stampare +il primo byte di una stringa o i valori numerici che possono essere +rappresentati in un singolo byte (0--255). +@end quotation + + +@item @code{%d}, @code{%i} +Stampa un numero intero in base decimale. +Le due lettere di controllo sono equivalenti. +(La specificazione @samp{%i} @`e ammessa per compatibilit@`a con ISO C.) + +@item @code{%e}, @code{%E} +Stampa un numero nella notazione scientifica (con uso di esponente). +Per esempio: + +@example +printf "%4.3e\n", 1950 +@end example + +@noindent +stampa @samp{1.950e+03}, con un totale di quattro cifre significative, tre +delle quali +seguono il punto che separa la parte intera da quella decimale +[in Italia si usa la virgola al posto del punto] +(L'espressione @samp{4.3} rappresenta due modificatori, +introdotti nella prossima @value{SUBSECTION}). +@samp{%E} usa @samp{E} invece di @samp{e} nell'output. + +@item @code{%f} +Stampa un numero in notazione a virgola mobile. +Per esempio: + +@example +printf "%4.3f", 1950 +@end example + +@noindent +stampa @samp{1950.000}, con un totale di quattro cifre significative, tre +delle quali vengono dopo il punto decimale. +(L'espressione @samp{4.3} rappresenta due modificatori, +introdotti nella prossima @value{SUBSECTION}). + +In sistemi che implementano il formato a virgola mobile, come specificato +dallo standard IEEE 754, il valore infinito negativo @`e rappresentato come +@samp{-inf} o @samp{-infinity}, +e l'infinito positivo come +@samp{inf} o @samp{infinity}. +Il valore speciale ``not a number'' [non @`e un numero] viene scritto come +@samp{-nan} o @samp{nan} +(@pxref{Definizioni matematiche}). + +@item @code{%F} +Come @samp{%f}, ma i valori di infinito e di ``not a number'' sono scritti +in lettere maiuscole. + +Il formato @samp{%F} @`e un'estensione POSIX allo standard ISO C; non tutti +i sistemi lo prevedono. In tali casi, +@command{gawk} usa il formato @samp{%f}. + +@item @code{%g}, @code{%G} +Stampa un numero usando o la notazione scientifica o quella a virgola +mobile, scegliendo la forma pi@`u concisa; se il risultato @`e stampato usando la +notazione scientifica, @samp{%G} usa @samp{E} invece di @samp{e}. + +@item @code{%o} +Stampa un numero intero in ottale, senza segno +(@pxref{Numeri non-decimali}). + +@item @code{%s} +Stampa una stringa. + +@item @code{%u} +Stampa un numero intero decimale, senza segno. +(Questo formato @`e poco usato, perch@'e tutti i numeri in @command{awk} +sono a virgola mobile; @`e disponibile principalmente per compatibilit@`a col +linguaggio C.) + +@item @code{%x}, @code{%X} +Stampa un intero esadecimale senza segno; +@samp{%X} usa le lettere da @samp{A} a @samp{F} +invece che da @samp{a} a @samp{f} +(@pxref{Numeri non-decimali}). + +@item @code{%%} +Stampa un solo carattere @samp{%}. +Questa notazione non serve per stampare alcun +argomento e ignora eventuali modificatori. +@end table + +@cindex angolo buio, caratteri di controllo del formato +@cindex @command{gawk}, caratteri di controllo del formato +@quotation NOTA +Quando si usano lettere di controllo del formato per numeri interi +per stampare valori esterni all'intervallo massimo disponibile nel +linguaggio C per i numeri interi, +@command{gawk} usa lo +specificatore di formato @samp{%g}. Se si specifica l'opzione @option{--lint} +sulla riga di comando (@pxref{Opzioni}), @command{gawk} +emette un messaggio di avvertimento. Altre versioni di @command{awk} possono +stampare valori non validi, o comportarsi in modo completamente differente. +@value{DARKCORNER} +@end quotation + +@node Modificatori di formato +@subsection Modificatori per specifiche di formato @code{printf} + +@cindex istruzione @code{printf}, modificatori +@cindex @code{printf}, istruzione, modificatori +@cindex modificatori@comma{} in specificatori di formato +Una specifica di formato pu@`o anche includere dei @dfn{modificatori} che +possono controllare che parte stampare del valore dell'elemento, e anche +quanto spazio utilizzare per stamparlo. +I modificatori sono posizionati tra il @samp{%} e la lettera che controlla +il formato. +Negli esempi seguenti verr@`a usato il simbolo del punto elenco ``@bullet{}'' per +rappresentare +spazi nell'output. Questi sono i modificatori previsti, nell'ordine in +cui possono apparire: + +@table @asis +@cindex differenze tra @command{awk} e @command{gawk}, tra istruzioni @code{print} e @code{printf} +@cindex istruzione @code{printf}, specificatori posizionali +@cindex @code{printf}, istruzione, specificatori posizionali +@c the code{} does NOT start a secondary +@cindex specificatori posizionali, istruzione @code{printf} +@item @code{@var{N}$} +Una costante intera seguita da un @samp{$} @`e uno @dfn{specificatore posizionale}. +Normalmente, le specifiche di formato sono applicate agli argomenti +nell'ordine in cui appaiono nella stringa di formato. Con uno specificatore +posizionale, la specifica di formato @`e applicata a un argomento +indicato per numero, invece che a quello che +sarebbe il prossimo argomento nella lista. Gli specificatori posizionali +iniziano a contare partendo da uno. Quindi: + +@example +printf "%s %s\n", "Non", "v'allarmate" +printf "%2$s %1$s\n", "v'allarmate", "Non" +@end example + +@noindent +stampa per due volte il famoso consiglio amichevole. + +A prima vista, questa funzionalit@`a non sembra di grande utilit@`a. +Si tratta in effetti di un'estensione @command{gawk}, pensata per essere +usata nella traduzione di messaggi emessi in fase di esecuzione. +@xref{Ordinamento di printf}, +che descrive come e perch@'e usare specificatori posizionali. +Per ora li possiamo ignorare. + +@item - @code{-} (Segno meno) +Il segno meno, usato prima del modificatore di larghezza (si veda pi@`u avanti +in questa lista), +richiede di allineare a sinistra +l'argomento mantenendo la larghezza specificata. Normalmente, l'argomento +@`e stampato allineato a destra, con la larghezza specificata. Quindi: + +@example +printf "%-6s", "pippo" +@end example + +@noindent +stampa @samp{pippo@bullet{}}. + +@item @var{spazio} +Applicabile a conversioni numeriche, richiede di inserire uno spazio prima +dei valori positivi e un segno meno prima di quelli negativi. + +@item @code{+} +Il segno pi@`u, usato prima del modificatore di larghezza (si veda pi@`u avanti +in questa lista), +richiede di mettere sempre un segno nelle conversioni numeriche, anche se +il dato da formattare ha valore positivo. Il @samp{+} prevale sul +modificatore @dfn{spazio}. + +@item @code{#} +Richiede di usare una ``forma alternativa'' per alcune lettere di controllo. +Per @samp{%o}, preporre uno zero. +Per @samp{%x} e @samp{%X}, preporre @samp{0x} o @samp{0X} se il +numero @`e diverso da zero. +Per @samp{%e}, @samp{%E}, @samp{%f}, e @samp{%F}, il risultato deve contenere +sempre un separatore decimale. +Per @code{%g} e @code{%G}, gli zeri finali non significativi non sono +tolti dal numero stampato. + +@item @code{0} +Uno @samp{0} (zero) iniziale serve a richiedere che l'output sia +riempito con zeri (invece che con spazi), prima delle cifre significative. +Questo si applica solo ai formati di output di tipo numerico. +Questo @dfn{flag} ha un effetto solo se la larghezza del campo @`e maggiore +di quella del valore da stampare. + +@item @code{'} +Un carattere di apice singolo o un apostrofo @`e un'estensione POSIX allo +standard ISO C. +Indica che la parte intera di un valore a virgola mobile, o la parte intera +di un valore decimale intero, ha un carattere di separazione delle migliaia. +Ci@`o @`e applicabile solo alle localizzazioni che prevedono un tale carattere. +Per esempio: + +@example +$ @kbd{cat migliaia.awk} @ii{Visualizza il programma sorgente} +@print{} BEGIN @{ printf "%'d\n", 1234567 @} +$ @kbd{LC_ALL=C gawk -f migliaia.awk} +@print{} 1234567 @ii{Risultato nella localizzazione} "C" +$ @kbd{LC_ALL=en_US.UTF-8 gawk -f migliaia.awk} +@print{} 1,234,567 @ii{Risultato nella localizzazione UTF inglese americana} +@end example + +@noindent +Per maggiori informazioni relative a localizzazioni e internazionalizzazioni, +si veda @ref{Localizzazioni}. + +@quotation NOTA +Il @dfn{flag} @samp{'} @`e una funzionalit@`a interessante, ma utilizza un +carattere che @`e fonte di complicazioni, perch@'e risulta difficila da usare nei +programmi scritti direttamente sulla riga di comando. Per informazioni sui +metodi appropriati per gestire la cosa, si veda @ref{Protezione}. +@end quotation + +@item @var{larghezza} +Questo @`e un numero che specifica la larghezza minima che deve occupare un +campo. L'inserimento di un numero tra il segno @samp{%} e il carattere +di controllo del formato fa s@`{@dotless{i}} che il campo si espanda a quella larghezza. +Il modo di default per fare questo @`e di aggiungere degli spazi a +sinistra. Per esempio: + +@example +printf "%6s", "pippo" +@end example + +@noindent +stampa @samp{@bullet{}pippo}. + +il valore di @var{larghezza} indica la larghezza minima, non la massima. Se +il valore dell'elemento richiede pi@`u caratteri della @var{larghezza} +specificata, questa pu@`o essere aumentata secondo necessit@`a. +Quindi, per esempio: + +@example +printf "%6s", "pippo-pluto" +@end example + +@noindent +stampa @samp{pippo-pluto}. + +Anteponendo un segno meno alla @var{larghezza} si richiede che l'output sia +esteso con spazi a destra, invece che a sinistra. + +@item @code{.@var{precisione}} +Un punto, seguito da una costante intera +specifica la precisione da usare nella stampa. +Il tipo di precisione varia a seconda della lettera di controllo: + +@table @asis +@item @code{%d}, @code{%i}, @code{%o}, @code{%u}, @code{%x}, @code{%X} +Minimo numero di cifre da stampare. + +@item @code{%e}, @code{%E}, @code{%f}, @code{%F} +Numero di cifre alla destra del separatore decimale. + +@item @code{%g}, @code{%G} +Massimo numero di cifre significative. + +@item @code{%s} +Massimo numero di caratteri della stringa che possono essere stampati. +@end table + +Quindi, l'istruzione: + +@example +printf "%.4s", "foobar" +@end example + +@noindent +stampa @samp{foob}. +@end table + +Le funzionalit@`a di @var{larghezza} e @var{precisione} dinamiche (cio@`e, +@code{"%*.*s"}) disponibili nell'istruzione @code{printf} della libreria C sono +utilizzabili. +Invece che fornire esplicitamente una @var{larghezza} e/o una @var{precisione} +nella stringa di formato, queste sono fornite come parte della lista degli +argomenti. Per esempio: + +@example +w = 5 +p = 3 +s = "abcdefg" +printf "%*.*s\n", w, p, s +@end example + +@noindent +equivale esattamente a: + +@example +s = "abcdefg" +printf "%5.3s\n", s +@end example + +@noindent +Entrambi i programmi stampano @samp{@w{@bullet{}@bullet{}abc}}. +Versioni pi@`u datate di @command{awk} non consentivano questa possibilit@`a. +Dovendo usare una di queste versioni, @`e possibile simulare questa +funzionalit@`a usando la concatenazione per costruire una stringa di formato, +come per esempio: + +@example +w = 5 +p = 3 +s = "abcdefg" +printf "%" w "." p "s\n", s +@end example + +@noindent +Questo codice non @`e di facile lettura, ma funziona. + +@c @cindex controlli @command @{lint} +@cindex debug, errori fatali, @code{printf}, stringhe di formato +@cindex POSIX @command{awk}, stringhe di formato @code{printf} e +Chi programma in C probabilmente @`e abituato a specificare modificatori +addizionali (@samp{h}, @samp{j}, @samp{l}, @samp{L}, @samp{t} e @samp{z}) nelle +stringhe di formato di @code{printf}. Questi modificatori non sono validi +in @command{awk}. La maggior parte della implementazioni di @command{awk} li +ignora senza emettere messaggi. Se si specifica l'opzione @option{--lint} +sulla riga di comando (@pxref{Opzioni}), @command{gawk} emette un messaggio +di avvertimento quando li si usa. Se si specifica l'opzione @option{--posix}, +il loro uso genera un errore fatale. + +@node Esempi su printf +@subsection Esempi d'uso di @code{printf} + +Il seguente semplice esempio mostra +come usare @code{printf} per preparare una tabella allineata: + +@example +awk '@{ printf "%-10s %s\n", $1, $2 @}' mail-list +@end example + +@noindent +Questo comando +stampa i nomi delle persone (@code{$1}) nel file +@file{mail-list} come una stringa di 10 caratteri allineati a sinistra. +Stampa anche i numeri telefonici (@code{$2}) a fianco, sulla stessa riga. +Il risultato @`e una tabella allineata, contenente due colonne, di nomi e numeri +telefonici, come si pu@`o vedere qui: + +@example +$ @kbd{awk '@{ printf "%-10s %s\n", $1, $2 @}' mail-list} +@print{} Amelia 555-5553 +@print{} Anthony 555-3412 +@print{} Becky 555-7685 +@print{} Bill 555-1675 +@print{} Broderick 555-0542 +@print{} Camilla 555-2912 +@print{} Fabius 555-1234 +@print{} Julie 555-6699 +@print{} Martin 555-6480 +@print{} Samuel 555-3430 +@print{} Jean-Paul 555-2127 +@end example + +In questo caso, i numeri telefonici debbono essere stampati come stringhe, +poich@'e includono un trattino. Una stampa dei numeri telefonici come numeri +semplici avrebbe visualizzato solo le prime tre cifre: @samp{555}, +e questo non sarebbe stato di grande utilit@`a. + +Non era necessario specificare una larghezza per i numeri telefonici poich@'e +sono nell'ultima colonnna di ogni riga. Non c'@`e bisogno di avere un +allineamento di spazi dopo di loro. + +La tabella avrebbe potuto essere resa pi@`u leggibile aggiungendo +intestazioni in cima +alle colonne. Questo si pu@`o fare usando una regola @code{BEGIN} +(@pxref{BEGIN/END}) +in modo che le intestazioni siano stampate una sola volta, all'inizio del +programma @command{awk}: + +@example +awk 'BEGIN @{ print "Nome Numero" + print "---- ------" @} + @{ printf "%-10s %s\n", $1, $2 @}' mail-list +@end example + +L'esempio precedente usa sia l'istruzione @code{print} che l'istruzione +@code{printf} nello stesso programma. Si possono ottenere gli stessi +risultati usando solo istruzioni @code{printf}: + +@example +awk 'BEGIN @{ printf "%-10s %s\n", "Nome", "Numero" + printf "%-10s %s\n", "----", "------" @} + @{ printf "%-10s %s\n", $1, $2 @}' mail-list +@end example + +@noindent +Stampare ogni intestazione di colonna con la stessa specifica di formato +usata per gli elementi delle colonne ci d@`a la certezza che le intestazioni +sono allineate esattamente come le colonne. + +Il fatto che usiamo per tre volte la stessa specifica di formato si pu@`o +evidenziare memorizzandola in una variabile, cos@`{@dotless{i}}: + +@example +awk 'BEGIN @{ format = "%-10s %s\n" + printf format, "Nome", "Numero" + printf format, "----", "------" @} + @{ printf format, $1, $2 @}' mail-list +@end example + + +@node Ridirezione +@section Ridirigere l'output di @code{print} e @code{printf} + +@cindex output, ridirezione +@cindex ridirezione dell'output +@cindex @option{--sandbox}, opzione, ridirezione dell'output con @code{print}, @code{printf} +Finora, l'output di @code{print} e @code{printf} @`e stato diretto +verso lo standard output, +che di solito @`e lo schermo. Sia @code{print} che @code{printf} possono +anche inviare il loro output in altre direzioni. +@`E quel che si chiama @dfn{ridirezione}. + +@quotation NOTA +Quando si specifica @option{--sandbox} (@pxref{Opzioni}), +la ridirezione dell'output verso file, @dfn{pipe} e coprocessi non @`e +consentita. +@end quotation + +Una ridirezione @`e posta dopo l'istruzione @code{print} o @code{printf}. +Le ridirezioni in @command{awk} sono scritte come le ridirezioni nei +comandi della shell, l'unica differenza @`e che si trovano all'interno di +un programma @command{awk}. + +@c the commas here are part of the see also +@cindex istruzione @code{print}, si veda anche ridirezione dell'output +@cindex istruzione @code{printf}, si veda anche ridirezione dell'output +Ci sono quattro forme di ridirezione dell'output: +output scritto su un file, +output aggiunto in fondo a un file, +output che fa da input a un altro comando (usando una @dfn{pipe}) e +output diretto a un coprocesso. +Vengono descritti per l'istruzione @code{print}, +ma funzionano allo stesso modo per @code{printf}: + +@table @code +@cindex @code{>} (parentesi acuta destra), operatore @code{>} (I/O) +@cindex parentesi acuta destra (@code{>}), operatore @code{>} (I/O) +@cindex operatori, input/output +@item print @var{elementi} > @var{output-file} +Questa ridirezione stampa gli elementi nel file di output chiamato +@var{output-file}. Il @value{FN} @var{output-file} pu@`o essere +una qualsiasi espressione. Il suo valore @`e trasformato in una stringa e +quindi usato come +@iftex +@value{FN} (@pxrefil{Espressioni}). +@end iftex +@ifnottex +@value{FN} (@pxref{Espressioni}). +@end ifnottex +Quando si usa questo tipo di ridirezione, il file @var{output-file} viene +cancellato prima che su di esso sia stato scritto il primo record in uscita. +Le successive scritture verso lo stesso file @var{output-file} non cancellano +@var{output-file}, ma continuano ad aggiungervi record. +(Questo comportamento @`e differente da quello delle ridirezioni usate negli +script della shell.) +Se @var{output-file} non esiste, viene creato. Per esempio, ecco +come un programma @command{awk} pu@`o scrivere una lista di nomi di persone +su un file di nome @file{lista-nomi}, e una lista di numeri telefonici +su un altro file di nome @file{lista-telefoni}: + +@example +$ @kbd{awk '@{ print $2 > "lista-telefoni"} +> @kbd{print $1 > "lista-nomi" @}' mail-list} +$ @kbd{cat lista-telefoni} +@print{} 555-5553 +@print{} 555-3412 +@dots{} +$ @kbd{cat lista-nomi} +@print{} Amelia +@print{} Anthony +@dots{} +@end example + +@noindent +Ogni file in output contiene un nome o un numero su ogni riga. + +@cindex @code{>} (parentesi acuta destra), operatore @code{>>} (I/O) +@cindex parentesi acuta destra (@code{>}), operatore @code{>>} (I/O) +@item print @var{elementi} >> @var{output-file} +Questa ridirezione stampa gli elementi in un file di output preesistente, +di nome @var{output-file}. La differenza tra questa ridirezione e quella +con un solo @samp{>} @`e che il precedente contenuto (se esiste) di +@var{output-file} non viene cancellato. Invece, l'output di @command{awk} @`e +aggiunto in fondo al file. +Se @var{output-file} non esiste, viene creato. + +@cindex @code{|} (barra verticale), operatore @code{|} (I/O) +@cindex @dfn{pipe}, output +@cindex output, a @dfn{pipe} +@item print @var{elementi} | @var{comando} +@`E possibile inviare output a un altro programma usando una @dfn{pipe} +invece di inviarlo a un file. Questa ridirezione apre una @dfn{pipe} verso +@var{comando}, e invia i valori di @var{elementi}, tramite questa +@dfn{pipe}, a un altro processo creato per eseguire @var{comando}. + +L'argomento @var{comando}, verso cui @`e rivolta la ridirezione, @`e in realt@`a +un'espressione +@command{awk}. Il suo valore @`e convertito in una stringa il cui contenuto +costituisce un comando della shell che deve essere eseguito. Per esempio, +il seguente programma produce due file, una lista non ordinata di nomi di +persone e una lista ordinata in ordine alfabetico inverso: + +@ignore +10/2000: +This isn't the best style, since COMMAND is assigned for each +record. It's done to avoid overfull hboxes in TeX. Leave it +alone for now and let's hope no-one notices. +@end ignore + +@example +awk '@{ print $1 > "nomi.non.ordinati" + comando = "sort -r > nomi.ordinati" + print $1 | comando @}' mail-list +@end example + +La lista non ordinata @`e scritta usando una ridirezione normale, mentre +la lista ordinata @`e scritta inviando una @dfn{pipe} in input al programma +di utilit@`a @command{sort}. + +Il prossimo esempio usa la ridirezione per inviare un messaggio alla +mailing list @code{bug-sistema}. Questo pu@`o tornare utile se si hanno +problemi con uno script @command{awk} eseguito periodicamente per la +manutenzione del sistema: + +@example +report = "mail bug-sistema" +print("Script awk in errore:", $0) | report +print("al record numero", FNR, "di", NOME_FILE) | report +close(report) +@end example + +La funzione @code{close()} @`e stata chiamata perch@'e @`e una buona idea chiudere +la @dfn{pipe} non appena tutto l'output da inviare alla @dfn{pipe} @`e stato +inviato. @xref{Chiusura file e @dfn{pipe}} +per maggiori informazioni. + +Questo esempio illustra anche l'uso di una variabile per rappresentare +un @var{file} o un @var{comando}; non @`e necessario usare sempre +una costante stringa. Usare una variabile @`e di solito una buona idea, +perch@'e (se si vuole riusare lo stesso file o comando) +@command{awk} richiede che il valore della stringa sia sempre scritto +esattamente nello stesso modo. + +@cindex coprocessi +@cindex @code{|} (barra verticale), operatore @code{|&} (I/O) +@cindex operatori, input/output +@cindex differenze tra @command{awk} e @command{gawk}, operatori di input/output +@item print @var{elementi} |& @var{comando} +Questa ridirezione stampa gli elementi nell'input di @var{comando}. +La differenza tra questa ridirezione e quella +con la sola @samp{|} @`e che l'output da @var{comando} +pu@`o essere letto tramite @code{getline}. +Quindi, @var{comando} @`e un @dfn{coprocesso}, che lavora in parallelo al +programma @command{awk}, ma @`e al suo servizio. + +Questa funzionalit@`a @`e un'estensione @command{gawk}, e non @`e disponibile in +POSIX @command{awk}. +@ifnotdocbook +@xref{Getline coprocesso}, +per una breve spiegazione. +@ref{I/O bidirezionale} +per un'esposizione pi@`u esauriente. +@end ifnotdocbook +@ifdocbook +@xref{Getline coprocesso} +per una breve spiegazione. +@xref{I/O bidirezionale} +per un'esposizione pi@`u esauriente. +@end ifdocbook +@end table + +Ridirigere l'output usando @samp{>}, @samp{>>}, @samp{|} o @samp{|&} +richiede al sistema di aprire un file, una @dfn{pipe} o un coprocesso solo se +il particolare @var{file} o @var{comando} che si @`e specificato non @`e gi@`a +stato utilizzato in scrittura dal programma o se @`e stato chiuso +dopo l'ultima scrittura. + +@cindex debug, stampare +@`E un errore comune usare la ridirezione @samp{>} per la prima istruzione +@code{print} verso un file, e in seguito usare @samp{>>} per le successive +scritture in output: + +@example +# inizializza il file +print "Non v'allarmate" > "guida.txt" +@dots{} +# aggiungi in fondo al file +print "Evitate generatori di improbabilit@`a" >> "guide.txt" +@end example + +@noindent +Questo @`e il modo in cui le ridirezioni devono essere usate lavorando +con la shell. Ma in @command{awk} ci@`o non @`e necessario. In casi di questo +genere, un programma dovrebbe +usare @samp{>} per tutte le istruzioni @code{print}, perch@'e il file di +output @`e aperto una sola volta. +(Usando sia @samp{>} che @samp{>>} nello stesso programma, l'output @`e prodotto +nell'ordine atteso. +Tuttavia il mischiare gli operatori per lo stesso file @`e sintomo di uno +stile di programmazione inelegante, e pu@`o causare confusione in chi legge +il programma.) + +@cindex differenze tra @command{awk} e @command{gawk}, limitazioni di implementazione +@cindex problemi di implementazione, @command{gawk}, limitazioni +@cindex @command{awk}, problemi di implementazione, @dfn{pipe} +@cindex @command{gawk}, problemi di implementazione, @dfn{pipe} +@ifnotinfo +Come visto in precedenza +(@pxref{Note su getline}), +molte +@end ifnotinfo +@ifnottex +@ifnotdocbook +@ifnothtml +Molte +@end ifnothtml +@end ifnotdocbook +@end ifnottex +tra le pi@`u vecchie implementazioni di +@command{awk} limitano il numero di @dfn{pipeline} che un programma +@command{awk} pu@`o mantenere aperte a una soltanto! In @command{gawk}, non c'@`e +un tale limite. @command{gawk} consente a un programma di +aprire tante @dfn{pipeline} quante ne consente il sistema operativo su cui +viene eseguito. + +@sidebar Inviare @dfn{pipe} alla @command{sh} +@cindex shell, inviare comandi tramite @dfn{pipe} alla + +Una maniera particolarmente efficace di usare la ridirezione @`e quella di +preparare righe di comando da passare +come @dfn{pipe} alla shell, +@command{sh}. Per esempio, si supponga di avere una lista di file provenienti +da un sistema in cui tutti i +@value{FNS} sono memorizzari in maiuscolo, e di volerli rinominare +in modo da avere nomi tutti in +minuscolo. Il seguente programma @`e +sia semplice che efficiente: + +@c @cindex @command{mv} utility +@example +@{ printf("mv %s %s\n", $0, tolower($0)) | "sh" @} + +END @{ close("sh") @} +@end example + +La funzione @code{tolower()} restituisce la stringa che gli viene passata +come argomento con tutti i caratteri maiuscoli convertiti in minuscolo +(@pxref{Funzioni per stringhe}). +Il programma costruisce una lista di righe di comando, +usando il programma di utilit@`a @command{mv} per rinominare i file. +Poi invia la lista alla shell per l'elaborazione. + +@xref{Apici alla shell} per una funzione che pu@`o essere utile nel generare +righe di comando da passare alla shell. +@end sidebar + +@node FD speciali +@section File speciali per flussi standard di dati pre-aperti +@cindex standard input +@cindex input, standard +@cindex standard output +@cindex output, standard +@cindex errore, output +@cindex standard error +@cindex descrittori di file +@cindex file, descrittori, si veda descrittori di file + +I programmi in esecuzione hanno convenzionalmente tre flussi di input e +output a disposizione, gi@`a aperti per la lettura e la scrittura. +Questi sono noti come +lo @dfn{standard input}, lo @dfn{standard output} e lo @dfn{standard +error output}. A questi flussi aperti (e a tutti gli altri file aperti o +@dfn{pipe}) si fa spesso riferimento usando il termine tecnico +@dfn{descrittori di file} [FD]. + +Questi flussi sono, per default, associati alla tastiera e allo schermo, +ma spesso sono ridiretti, nella shell, utilizzando gli operatori +@samp{<}, @samp{<<}, @samp{>}, @samp{>>}, @samp{>&} e @samp{|}. +Lo standard error @`e tipicamente usato per scrivere messaggi di errore; +la ragione per cui ci sono due flussi distinti, +standard output e standard error, @`e per poterli ridirigere indipendentemente +l'uno dall'altro. + +@cindex differenze tra @command{awk} e @command{gawk}, messaggi di errore +@cindex gestione errori +@cindex errori, gestione degli +Nelle tradizionali implementazioni di @command{awk}, il solo modo per +scrivere un messaggio di errore allo +standard error in un programma @command{awk} @`e il seguente: + +@example +print "Ho trovato un errore grave!" | "cat 1>&2" +@end example + +@noindent +Con quest'istruzione si apre una @dfn{pipeline} verso un comando della shell +che @`e in grado di accedere al flusso di standard error che eredita dal +processo @command{awk}. +@c 8/2014: Mike Brennan says not to cite this as inefficient. So, fixed. +Questo @`e molto poco elegante, e richiede anche di innescare un processo +separato. Per questo chi scrive programmi @command{awk} spesso +non usa questo metodo. Invece, invia i messaggi di errore allo +schermo, in questo modo: + +@example +print "Ho trovato un errore grave!" > "/dev/tty" +@end example + +@noindent +(@file{/dev/tty} @`e un file speciale fornito dal sistema operativo +ed @`e connesso alla tastiera e allo schermo. Rappresenta il +``terminale'',@footnote{``tty'' in @file{/dev/tty} @`e un'abbreviazione di +``TeleTYpe'' [telescrivente], un terminale seriale.} che nei sistemi odierni +@`e una tastiera e uno schermo, e non una @dfn{console} seriale). +Questo ha generalmente lo stesso effetto, ma non @`e sempre detto: sebbene il +flusso di standard error sia solitamente diretto allo schermo, potrebbe +essere stato +ridiretto; se questo @`e il caso, scrivere verso lo schermo non serve. In +effetti, se @command{awk} @`e chiamato da un lavoro che non @`e eseguito +interattivamente, +pu@`o non avere a disposizione alcun terminale su cui scrivere. +In quel caso, l'apertura di @file{/dev/tty} genera un errore. + +@command{gawk}, BWK @command{awk}, e @command{mawk} mettono a disposizione +speciali @value{FNS} per accedere ai tre flussi standard. +Se il @value{FN} coincide con uno di questi nomi speciali, quando +@command{gawk} (o uno degli altri) ridirige l'input o l'output, usa +direttamente il descrittore di file identificato dal @value{FN}. Questi +@value{FNS} sono gestiti cos@`{@dotless{i}} in tutti i sistemi operativi nei quali +@command{gawk} @`e disponibile, e non solo in quelli che aderiscono allo +standard POSIX: + +@cindex estensioni comuni, file speciale @code{/dev/stdin} +@cindex estensioni comuni, file speciale @code{/dev/stdout} +@cindex estensioni comuni, file speciale @code{/dev/stderr} +@c @cindex comuni, estensioni@comma{} file speciale @code{/dev/stdin} +@c @cindex comuni, estensioni@comma{} file speciale @code{/dev/stdout} +@c @cindex comuni, estensioni@comma{} file speciale @code{/dev/stderr} +@cindex nomi di file, flussi standard in @command{gawk} +@cindex @code{/dev/@dots{}}, file speciali +@cindex file, file speciali @code{/dev/@dots{}} +@cindex @code{/dev/fd/@var{N}}, file speciali (in @command{gawk}) +@table @file +@item /dev/stdin +Lo standard input (descrittore di file 0). + +@item /dev/stdout +Lo standard output (descrittore di file 1). + +@item /dev/stderr +Lo standard error output (descrittore di file 2). +@end table + +Usando questa funzionalit@`a +la maniera corretta di scrivere un messaggio di errore diviene quindi: + +@example +print "Ho trovato un errore grave!" > "/dev/stderr" +@end example + +@cindex debug, doppio apice con nomi di file +Si noti l'uso di doppi apici per racchiudere il @value{FN}. +Come per ogni altra ridirezione, il valore dev'essere una stringa. +@`E un errore comune omettere i doppi apici, il che conduce a +risultati inattesi. + +@command{gawk} non tratta questi @value{FNS} come speciali quando opera +in modalit@`a di compatibilit@`a POSIX. Comunque, poich@'e BWK @command{awk} +li prevede, @command{gawk} li ammette anche quando viene +invocato con l'opzione @option{--traditional} (@pxref{Opzioni}). + +@node File speciali +@section @value{FFNS} speciali in @command{gawk} +@cindex @command{gawk}, nomi di file in + +Oltre all'accesso a standard input, standard output e standard error, +@command{gawk} consente di accedere a ogni descrittore di file aperto. +In pi@`u, ci sono dei @value{FNS} speciali riservati per accedere a +reti TCP/IP. + +@menu +* Altri file ereditati:: Accedere ad altri file aperti con + @command{gawk}. +* Reti speciali:: File speciali per comunicazioni con la rete. +* Avvertimenti speciali:: Cose a cui prestare attenzione. +@end menu + +@node Altri file ereditati +@subsection Accedere ad altri file aperti con @command{gawk} + +Oltre ai valori speciali di @value{FNS} +@code{/dev/stdin}, @code{/dev/stdout} e @code{/dev/stderr} +gi@`a menzionati, @command{gawk} prevede una sintassi +per accedere a ogni altro file aperto ereditato: + +@table @file +@item /dev/fd/@var{N} +Il file associato al descrittore di file @var{N}. Il file indicato deve +essere aperto dal programma che inizia l'esecuzione di @command{awk} +(tipicamente la shell). Se non sono state poste in essere iniziative +speciali nella shell da cui @command{gawk} @`e stato invocato, solo i +descrittori 0, 1, e 2 sono disponibili. +@end table + +I @value{FNS} @file{/dev/stdin}, @file{/dev/stdout} e @file{/dev/stderr} +sono essenzialmente alias per @file{/dev/fd/0}, @file{/dev/fd/1} e +@file{/dev/fd/2}, rispettivamente. Comunque, i primi nomi sono pi@`u +autoesplicativi. + +Si noti che l'uso di @code{close()} su un @value{FN} della forma +@code{"/dev/fd/@var{N}"}, per numeri di descrittore di file +oltre il due, effettivamente chiude il descrittore di file specificato. + +@node Reti speciali +@subsection File speciali per comunicazioni con la rete +@cindex reti, funzionalit@`a per +@cindex TCP/IP, funzionalit@`a per + +I programmi @command{gawk} +possono aprire una connessione bidirezionale +TCP/IP, fungendo o da @dfn{client} o da @dfn{server}. +Questo avviene usando uno speciale @value{FN} della forma: + +@example +@file{/@var{tipo-rete}/@var{protocollo}/@var{porta-locale}/@var{host-remoto}/@var{porta-remota}} +@end example + +il @var{tipo-rete} pu@`o essere @samp{inet}, @samp{inet4} o @samp{inet6}. +Il @var{protocollo} pu@`o essere @samp{tcp} o @samp{udp}, +e gli altri campi rappresentano gli altri dati essenziali +necessari per realizzare una connessione di rete. +Questi @value{FNS} sono usati con l'operatore @samp{|&} per comunicare +con un coprocesso +(@pxref{I/O bidirezionale}). +Questa @`e una funzionalit@`a avanzata, qui riferita solo per completezza. +Una spiegazione esauriente sar@`a fornita nella +@ref{Reti TCP/IP}. + +@node Avvertimenti speciali +@subsection Avvertimenti speciali sui @value{FNS} + +Sono qui elencate alcune cose da tener presente usando i +@value{FNS} speciali forniti da @command{gawk}: + +@itemize @value{BULLET} +@cindex modalit@`a compatibile di (@command{gawk}), nomi di file +@cindex nomi di file, nella modalit@`a compatibile di @command{gawk} +@item +Il riconoscimento dei @value{FNS} per i tre file standard pre-aperti +@`e disabilitato solo in modalit@`a POSIX. + +@item +Il riconoscimento degli altri @value{FNS} speciali @`e disabilitato se +@command{gawk} @`e in modalit@`a compatibile +(o @option{--traditional} o @option{--posix}; +@pxref{Opzioni}). + +@item +@command{gawk} interpreta @emph{sempre} +questi @value{FNS} speciali. +Per esempio, se si usa @samp{/dev/fd/4} +per l'output, si scrive realmente sul descrittore di file 4, e non su un nuovo +descrittore di file generato duplicando (con @code{dup()}) il descrittore +file 4. Solitamente questo non ha importanza; comunque, @`e importante +@emph{non} chiudere alcun file correlato ai descrittori di file 0, 1 e 2. +Se lo si fa, il comportamente risultante @`e imprevedibile. +@end itemize + +@node Chiusura file e @dfn{pipe} +@section Chiudere ridirezioni in input e in output +@cindex output, file in, si veda file in output +@cindex input, file in, chiusura +@cindex output, file in, chiusura +@cindex @dfn{pipe}, chiusura +@cindex coprocessi, chiusura +@cindex @code{getline}, comando, coprocessi@comma{} usare dal + +Se lo stesso @value{FN} o lo stesso comando di shell @`e usato con @code{getline} +pi@`u di una volta durante l'esecuzione di un programma @command{awk} +(@pxref{Getline}), +il file viene aperto (o il comando viene eseguito) solo la prima volta. +A quel punto, il primo record in input @`e letto da quel file o comando. +La prossima volta che lo stesso file o comando @`e usato con @code{getline}, +un altro record @`e letto da esso, e cos@`{@dotless{i}} via. + +Analogamente, quando un file o una @dfn{pipe} sono aperti in output, +@command{awk} ricorda +il @value{FN} o comando a essi associato, e le successive +scritture verso lo stesso file o comando sono accodate alle precedenti +scritture. +Il file o la @dfn{pipe} rimangono aperti fino al termine dell'esecuzione +di @command{awk}. + +@cindexawkfunc{close} +Questo implica che sono necessari dei passi speciali per rileggere nuovamente +lo stesso file dall'inizio, o per eseguire di nuovo un comando di shell +(invece che leggere ulteriore output dal precedente comando). La funzione +@code{close()} rende possibile fare queste cose: + +@example +close(@var{NOME_FILE}) +@end example + +@noindent +o: + +@example +close(@var{comando}) +@end example + +l'argomento @var{NOME_FILE} o @var{comando} pu@`o essere qualsiasi espressione, +il cui valore dev'essere @emph{esattamente} uguale alla stringa +usata per aprire il file o eseguire il comando (spazi e altri caratteri +``irrilevanti'' inclusi). Per esempio, se si apre una @dfn{pipe} cos@`{@dotless{i}}: + +@example +"sort -r nomi" | getline pippo +@end example + +@noindent +essa va chiusa in questo modo: + +@example +close("sort -r nomi") +@end example + +Una volta eseguita questa chiamata di funzione, la successiva @code{getline} +da quel file o comando, o la successiva @code{print} o @code{printf} verso quel +file o comando, riaprono il file o eseguono nuovamente il comando. +Poich@'e l'espressione da usare per chiudere un file o una @dfn{pipeline} deve +essere uguale all'espressione usata per aprire il file o eseguire il comando, +@`e buona norma usare una variabile che contenga il @value{FN} o il comando. +Il precedente esempio cambia come segue: + +@example +sortcom = "sort -r nomi" +sortcom | getline pippo +@dots{} +close(sortcom) +@end example + +@noindent +Questo aiuta a evitare nei programmi @command{awk} errori di battitura +difficili da scoprire. Queste sono alcune delle ragioni per cui @`e bene +chiudere un file di output: + +@itemize @value{BULLET} +@item +Scrivere un file e rileggerlo in seguito all'interno dello stesso programma +@command{awk}. Occorre chiudere il file dopo aver finito di scriverlo, e poi +iniziare a rileggerlo con @code{getline}. + +@item +Per scrivere numerosi file, uno dopo l'altro, nello stesso programma +@command{awk}. Se i file non vengono chiusi, prima o poi @command{awk} pu@`o +superare il limite di sistema per il numero di file aperti in un processo. +@`E meglio chiudere ogni file quando il programma ha finito di scriverlo. + +@item +Per terminare un comando. Quando l'output @`e ridiretto usando una @dfn{pipe}, +il comando che legge la @dfn{pipe} normalmente continua a tentare di leggere +input finch@'e la @dfn{pipe} rimane aperta. Spesso questo vuol dire che +il comando non pu@`o eseguire il compito a lui assegnato finch@'e la @dfn{pipe} +non viene chiusa. Per esempio, se l'output @`e ridiretto al programma +@command{mail}, il messaggio non @`e effettivamente inviato finch@'e la @dfn{pipe} +non viene chiusa. + +@item +Eseguire lo stesso programma una seconda volta, con gli stessi argomenti. +Questo non equivale a fornire ulteriore input alla prima esecuzione! + +Per esempio, si supponga che una programma invii tramite una @dfn{pipe} +dell'output al programma @command{mail}. +Se invia parecchie linee ridirigendole a questa @dfn{pipe} senza chiuderla, +queste costituiscono un solo messaggio di parecchie righe. Invece, se il +programma chiude la @dfn{pipe} dopo ogni riga dell'output, allora ogni riga +costituisce un messaggio separato. +@end itemize + +@cindex differenze tra @command{awk} e @command{gawk}, funzione @code{close()} +@cindex portabilit@`a, funzione @code{close()} +@cindex funzione @code{close()}, portabilit@`a +@cindex @code{close()}, funzione, portabilit@`a +Se si usano file in numero superiore a quelli che il sistema permette +di mantenere aperti, +@command{gawk} tenta di riutilizzare i file aperti disponibili fra +i @value{DF}. La possibilit@`a che @command{gawk} lo faccia dipende dalle +funzionalit@`a del sistema operativo, e quindi non @`e detto che questo riesca +sempre. @`E quindi sia una buona pratica +che un buon suggerimento per la portabilit@`a quello di usare sempre +@code{close()} sui file, una volta che si @`e finito di operare su di essi. +In effetti, se si usano molte @dfn{pipe}, @`e fondamentale che i comandi +vengano chiusi, una volta finita la loro elaborazione. Per esempio, si +consideri qualcosa del tipo: + +@example +@{ + @dots{} + comando = ("grep " $1 " /qualche/file | un_mio_programma -q " $3) + while ((comando | getline) > 0) @{ + @var{elabora output di} comando + @} + # qui serve close(comando) +@} +@end example + +Questo esempio crea una nuova @dfn{pipeline} a seconda dei dati contenuti in +@emph{ogni} record. +Senza la chiamata a @code{close()} indicata come commento, @command{awk} +genera processi-figlio per eseguire i comandi, fino a che non finisce per +esaurire i descrittori di file +necessari per creare ulteriori @dfn{pipeline}. + +Sebbene ogni comando sia stato completato (come si deduce dal codice di +fine-file restituito dalla @code{getline}), il processo-figlio non @`e +terminato;@footnote{La terminologia tecnica @`e piuttosto macabra. +Il processo-figlio terminato @`e chiamato ``zombie,'' e la pulizia alla fine +dello stesso @`e chiamata ``reaping'' [mietitura].} +@c Good old UNIX: give the marketing guys fits, that's the ticket +inoltre, e questo @`e ci@`o che pi@`u ci interessa, il descrittore di file +per la @dfn{pipe} non @`e chiuso e liberato finch@'e non si chiama +@code{close()} o finch@'e il programma @command{awk} non termina. + +@code{close()} non fa nulla (e non emette messaggi) se le viene fornito come +argomento una stringa che non rappresenta un file, una @dfn{pipe} o un +coprocesso che sia stato aperto mediante una ridirezione. In quel caso, +@code{close()} restituisce un valore di ritorno negativo, che indica un +errore. Inoltre, @command{gawk} imposta @code{ERRNO} +a una stringa che indica il tipo di errore. + +Si noti anche che @samp{close(NOME_FILE)} non ha effetti ``magici'' sul ciclo +implicito che legge ogni record dei file indicati nella riga di comando. +Si tratta, con ogni probabilit@`a, della chiusura di un file che non era mai +stato aperto con una ridirezione, +e per questo @command{awk} silenziosamente non fa nulla, tranne impostare un +codice di ritorno negativo. + +@cindex @code{|} (barra verticale), operatore @code{|&} (I/O), @dfn{pipe}@comma{} chiusura +Quando si usa l'operatore @samp{|&} per comunicare con un coprocesso, +@`e talora utile essere in grado di chiudere un lato della @dfn{pipe} +bidirezionale, senza chiudere l'altro lato. +Questo @`e possibile fornendo un secondo argomento a @code{close()}. +Come in ogni altra invocazione di @code{close()}, +il primo argomento @`e il nome del comando o file speciale usato +per iniziare il coprocesso. +Il secondo argomento dovrebbe essere una stringa, con uno dei due valori +@code{"to"} [a] oppure @code{"from"} [da]. Maiuscolo/minuscolo non fa +differenza. Poich@'e questa @`e una funzionalit@`a avanzata, la trattazione @`e +rinviata alla +@ref{I/O bidirezionale}, +che ne parla pi@`u dettagliatamente e fornisce un esempio. + +@sidebar Usare il valore di ritorno di @code{close()} +@cindex angolo buio, funzione @code{close()} +@cindex funzione @code{close()}, valore di ritorno +@cindex @code{close()}, funzione, valore di ritorno +@cindex valore di ritorno@comma{} funzione @code{close()} +@cindex differenze tra @command{awk} e @command{gawk}, funzione @code{close()} +@cindex Unix @command{awk}, funzione @code{close()} e + +In molte versioni di Unix @command{awk}, la funzione @code{close()} +@`e in realt@`a un'istruzione. +@value{DARKCORNER} +@`E un errore di sintassi tentare di usare il valore +di ritorno da @code{close()}: + +@example +comando = "@dots{}" +comando | getline info +retval = close(comando) # errore di sintassi in parecchi Unix awk +@end example + +@cindex @command{gawk}, variabile @code{ERRNO} in +@cindex variabile @code{ERRNO}, con funzione @command{close()} +@cindex @code{ERRNO}, variabile, con funzione @command{close()} +@command{gawk} gestisce @code{close()} come una funzione. +Il valore di ritorno @`e @minus{}1 se l'argomento designa un file +che non era mai stato aperto con una ridirezione, o se c'@`e un problema di +sistema nella chiusura del file o del processo. +In tal caso, @command{gawk} imposta la variabile predefinita +@code{ERRNO} a una stringa che descrive il problema. + +In @command{gawk}, a partire dalla @value{PVERSION} 4.2, +quando si chiude una @dfn{pipe} o un coprocesso (in input o in output), +il valore di ritorno @`e quello restituito dal comando, +come descritto in @ref{table-close-pipe-return-values}.@footnote{Prima +della @value{PVERSION} 4.2, il valore di ritorno dopo la chiusura di +una @dfn{pipe} o di un coprocesso era una cifra di due byte (16-bit), +contenente il valore restituito dalla chiamata di sistema @code{wait()}}. +Altrimenti, @`e il valore di ritorno dalla chiamata alle funzione +di sistema @code{close()} o alla funzione C @code{fclose()} +se si sta chiudendo un file in input o in output, rispettivamente. +Questo valore @`e zero se la chiusura riesce, o @minus{}1 se non riesce. + +@float Tabella,table-close-pipe-return-values +@caption{Valori di ritorno dalla @code{close()} di una @dfn{pipe}} +@multitable @columnfractions .50 .50 +@headitem Situazione @tab Valore restituito da @code{close()} +@item Uscita normale dal comando @tab Il codice di ritorno del comando +@item Uscita dal comando per @dfn{signal} @tab 256 + numero del segnale assassino +@item Uscita dal comando per @dfn{signal} con @dfn{dump} @tab 512 + numero del segnale assassino +@item Errore di qualsiasi tipo @tab @minus{}1 +@end multitable +@end float + +Lo standard POSIX @`e molto generico; dice che @code{close()} +restituisce zero se @`e terminata correttamente, e un valore diverso da zero +nell'altro caso. In generale, +implementazioni differenti variano in quel che restituiscono chiudendo una +@dfn{pipe}; quindi, il valore di ritorno non pu@`o essere usato in modo +portabile. +@value{DARKCORNER} +In modalit@`a POSIX (@pxref{Opzioni}), @command{gawk} restituisce solo zero +quando chiude una @dfn{pipe}. +@end sidebar + +@node Continuazione dopo errori +@section Abilitare continuazione dopo errori in output + +Questa @value{SECTION} descrive una funzionalit@`a specifica di @command{gawk}. + +In @command{awk} standard, l'output con @code{print} o @code{printf} +a un file che non esiste, o qualche altro errore di I/O (come p.es. +esaurire lo spazio disponibile su disco) @`e un errore fatale (termina +l'esecuzione del programma). + +@example +$ @kbd{gawk 'BEGIN @{ print "ciao" > "/file/non/esistente" @}'} +@error{} gawk: riga com.:1: fatale: non riesco a ri-dirigere a +@error{} `/file/non/esistente' (/file o directory non esistente) +@end example + +@command{gawk} rende possibile accorgersi che c'@`e stato un errore, +permettendo di tentare di rimediare, o almeno di stampare un messaggio +di errore prima di terminare il programma. +@`E possibile fare questo in due modi differenti: + +@itemize @bullet +@item +Per tutti i file in output, assegnando un valore qualsiasi a +@code{PROCINFO["NONFATAL"]}. + +@item +Specificamente per un solo file, assegnando un valore qualsiasi a +@code{PROCINFO[@var{nome_file}, "NONFATAL"]}. +@var{nome_file} @`e il nome del file per il quale +si desidera che l'errore di output non faccia terminare il programma. +@end itemize + +Una volta abilitata la continuazione dopo un errore di output, si dovr@`a +controllare la variabile @code{ERRNO} dopo ogni istruzione +@code{print} o @code{printf} diretta a quel file, per controllare che +tutto sia andato a buon fine. @`E anche una buona idea inizializzare +@code{ERRNO} a zero prima di tentare l'operazione di scrittura. +Per esempio: + +@example +$ @kbd{gawk '} +> @kbd{BEGIN @{} +> @kbd{ PROCINFO["NONFATAL"] = 1} +> @kbd{ ERRNO = 0} +> @kbd{ print "ciao" > "/file/non/esistente"} +> @kbd{ if (ERRNO) @{} +> @kbd{ print("Output non riuscito:", ERRNO) > "/dev/stderr"} +> @kbd{ exit 1} +> @kbd{ @}} +> @kbd{@}'} +@error{} Output non riuscito: No such file or directory +@end example + +@command{gawk} non genera un errore fatale; permette invece +al programma @command{awk} di rendersi conto del problema e di gestirlo. + +Questo meccanismo si applica anche allo standard output e allo standard error. +Per lo standard output, si pu@`o usare @code{PROCINFO["-", "NONFATAL"]} +o @code{PROCINFO["/dev/stdout", "NONFATAL"]}. +Per lo standard error, occorre +usare @code{PROCINFO["/dev/stderr", "NONFATAL"]}. + +Se si tenta di aprire un @dfn{socket} TCP/IP (@pxref{Reti TCP/IP}), +@command{gawk} tenta di farlo per un certo numero di volte. +La variabile d'ambiente @env{GAWK_SOCK_RETRIES} +(@pxref{Altre variabili d'ambiente}) consente di alterare il numero di +tentativi che @command{gawk} farebbe per default. Tuttavia, +una volta abilitata la continuazione dopo un errore di I/O per un certo +@dfn{socket}, @command{gawk} si limita a un solo tentativo, +lasciando al codice del programma @command{awk} il compito di gestire +l'eventuale problema. + +@node Sommario di Output +@section Sommario. + +@itemize @value{BULLET} +@item +L'istruzione @code{print} stampa una lista di espressioni separate da virgole. +Le espressioni sono separate tra loro dal valore di @code{OFS} e completate +dal valore di @code{ORS}. @code{OFMT} fornisce il formato di conversione +dei valori numerici per l'istruzione @code{print}. + +@item +L'istruzione @code{printf} fornisce un controllo pi@`u preciso sull'output, +con lettere di controllo del formato per diversi tipi di dati e vari +modificatori +che cambiano il comportamento delle lettere di controllo del formato. + +@item +L'output sia di @code{print} che di @code{printf} pu@`o essere ridiretto a +file, @dfn{pipe}, e coprocessi. + +@item +@command{gawk} fornisce @value{FNS} speciali per accedere allo +standard input, standard output e standard error, e per comunicazioni di rete. + +@item +Usare @code{close()} per chiudere file aperti, @dfn{pipe} e ridirezioni a +coprocessi. +Per i coprocessi, @`e possibile chiudere anche soltanto una delle due +direzioni di comunicazione. + +@item +Normalmente se si verificano errori eseguendo istruzioni @code{print} o +@code{printf}, questi causano la fine del programma. +@command{gawk} consente di proseguire l'elaborazione anche in questo +caso, o per un errore su qualsiasi file in output, o per un errore +relativo a qualche file in particolare. +Resta a carico del programma controllare se si sono verificati errori +dopo l'esecuzione di ogni istruzione di output interessata. + +@end itemize + +@c EXCLUDE START +@node Esercizi su Output +@section Esercizi + +@enumerate +@item +Riscrivere il programma: + +@example +awk 'BEGIN @{ print "Mese Contenitori" + print "----- -----------" @} + @{ print $1, $2 @}' inventory-shipped +@end example + +@noindent +come +@iftex +nella +@end iftex +@ifnottex +in +@end ifnottex +@ref{Separatori di output}, usando un nuovo valore per @code{OFS}. + +@item +Usare l'istruzione @code{printf} per allineare le intestazioni e i dati +della tabella +per il file di esempio @file{inventory-shipped} utilizzato nella @ref{Print}. + +@item +Spiegare cosa succede se si dimenticano i doppi apici ridirigendo l'output, +come nel caso che segue: + +@example +BEGIN @{ print "Ho trovato un errore grave!" > /dev/stderr @} +@end example + +@end enumerate +@c EXCLUDE END + + +@node Espressioni +@chapter Espressioni +@cindex espressioni + +Le espressioni sono i mattoni fondamentali dei modelli di ricerca e delle +azioni di @command{awk}. Un'espressione genera un valore che si +pu@`o stampare, verificare o passare a una funzione. Oltre a ci@`o, un'espressione +pu@`o assegnare un nuovo valore a una variabile o a un campo usando un operatore +di assegnamento. + +Un'espressione pu@`o servire come modello di ricerca o istruzione di azione a +s@'e stante. La maggior parte degli altri tipi di istruzione contengono una o +pi@`u espressioni che specificano i dati sui quali operare. Come in altri +linguaggi, le espressioni in @command{awk} possono includere variabili, +riferimenti a vettori e a costanti, e chiamate di funzione, come pure +combinazioni tra questi usando diversi operatori. + +@menu +* Valori:: Costanti, variabili ed espressioni regolari. +* Tutti gli operatori:: Gli operatori di @command{gawk}. +* Valori e condizioni di verit@`a:: Determinare Vero/Falso. +* Chiamate di funzione:: Una chiamata di funzione pu@`o essere + un'espressione. +* Precedenza:: Come si nidificano i vari operatori. +* Localizzazioni:: Come la localizzazione influenza la + gestione dati. +* Sommario delle espressioni:: Sommario delle espressioni. +@end menu + +@node Valori +@section Costanti, variabili e conversioni + +Le espressioni sono costruite a partire da valori e dalle operazioni eseguite +su di essi. Questa @value{SECTION} descrive gli oggetti elementari +che forniscono i valori usati nelle espressioni. + +@menu +* Costanti:: Costanti di tipo stringa, numeriche ed + espressioni regolari +* Usare le costanti @dfn{regexp}:: Quando e come usare una costante + specificata tramite espressioni regolari +* Variabili:: Le variabili permettono di + definire valori da usare in seguito. +* Conversione:: La conversione di stringhe in numeri + e viceversa. +@end menu + +@node Costanti +@subsection Espressioni costanti + +@cindex costanti, tipi di + +Il tipo di espressione pi@`u semplice @`e una @dfn{costante}, che ha sempre lo +stesso valore. Ci sono tre tipi di costanti: numeriche, di stringa e di +espressione regolare. + +Ognuna di esse si usa nel contesto appropriato quando occorre assegnare ai +dati un valore che non dovr@`a essere cambiato. Le costanti numeriche possono +avere forme diverse, ma sono memorizzate internamente sempre allo stesso modo. + +@menu +* Costanti scalari:: Costanti numeriche e stringhe. +* Numeri non-decimali:: Cosa sono i numeri ottali ed esadecimali. +* Costanti come espressioni regolari:: Costanti fornite tramite espressioni + regolari. +@end menu + +@node Costanti scalari +@subsubsection Costanti numeriche e stringhe + +@cindex costanti numeriche +@cindex numeriche, costanti +Una @dfn{costante numerica} @`e un numero. Questo numero pu@`o essere un +numero intero, una frazione decimale o un numero in notazione scientifica +(esponenziale).@footnote{La rappresentazione interna di tutti i numeri, +compresi gli interi, usa numeri in virgola mobile a doppia precisione. +Sui sistemi pi@`u moderni, questi sono nel formato standard IEEE 754. +@xref{Calcolo con precisione arbitraria}, per maggiori informazioni.} +Ecco alcuni esempi di costanti numeriche che hanno tutte lo stesso +valore: + +@example +105 +1.05e+2 +1050e-1 +@end example + +@cindex costanti stringa +Una @dfn{costante stringa} @`e formata da una sequenza di caratteri racchiusi tra +doppi apici. Per esempio: + +@example +"pappagallo" +@end example + +@noindent +@cindex differenze tra @command{awk} e @command{gawk}, stringhe +@cindex stringhe, limitazioni della lunghezza +rappresenta la stringa il cui contenuto @`e la parola @samp{pappagallo}. +Le stringhe in +@command{gawk} possono essere di qualsiasi lunghezza, e possono contenere +tutti i possibili caratteri ASCII a otto bit, compreso il carattere ASCII +@sc{nul} (carattere con codice zero). +Altre implementazioni di @command{awk} possono avere difficolt@`a con alcuni +particolari codici di carattere. + +@node Numeri non-decimali +@subsubsection Numeri ottali ed esadecimali +@cindex ottali, numeri +@cindex esadecimali, numeri +@cindex numeri ottali +@cindex numeri esadecimali + +In @command{awk}, tutti i numeri sono espressi nel sistema decimale (cio@`e a +base 10). +Molti altri linguaggi di programmazione consentono di specificare i numeri in +altre basi, spesso in ottale (base 8) e in esadecimale (base 16). +Nel sistema ottale i numeri hanno la sequenza 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, +12, e cos@`{@dotless{i}} via. Come @samp{11} decimale @`e una volta 10 pi@`u 1, cos@`{@dotless{i}} +@samp{11} ottale @`e una volta 8 pi@`u 1. Questo equivale a 9 nel sistema decimale. +Nell'esadecimale ci sono 16 cifre. Poich@'e l'usuale sistema numerico decimale +ha solo dieci cifre (@samp{0}--@samp{9}), le lettere da +@samp{a} a @samp{f} rappresentano le cifre ulteriori. +(normalmente @`e irrilevante se le lettere sono maiuscole o minuscole; gli +esadecimali @samp{a} e @samp{A} hanno lo stesso valore). +Cos@`{@dotless{i}}, @samp{11} esadecimale @`e 1 volta 16 pi@`u 1, +il che equivale a 17 decimale. + +Guardando solamente un @samp{11} puro e semplice, non si capisce in quale base +sia. Cos@`{@dotless{i}}, in C, C++, e in altri linguaggi derivati da C, +@c such as PERL, but we won't mention that.... +c'@`e una speciale notazione per esprimere la base. +I numeri ottali iniziano con uno @samp{0}, +e i numeri esadecimali iniziano con uno @samp{0x} o @samp{0X}: + +@table @code +@item 11 +Valore decimale 11 + +@item 011 +11 ottale, valore decimale 9 + +@item 0x11 +11 esadecimale, valore decimale 17 +@end table + +Quest'esempio mostra le differenze: + +@example +$ @kbd{gawk 'BEGIN @{ printf "%d, %d, %d\n", 011, 11, 0x11 @}'} +@print{} 9, 11, 17 +@end example + +Poter usare costanti ottali ed esadecimali nei propri programmi @`e molto utile +quando si lavora con dati che non possono essere rappresentati +convenientemente come caratteri o come numeri regolari, come i dati binari di +vario tipo. + +@cindex @command{gawk}, numeri ottali e +@cindex @command{gawk}, numeri esadecimali e +@command{gawk} permette l'uso di costanti ottali ed esadecimali nel testo di +un programma. Comunque, se numeri non-decimali sono presenti tra i dati in +input, essi non sono trattati in maniera speciale; trattarli in modo speciale +per default significherebbe che vecchi programmi @command{awk} produrrebbero +risultati errati. +(Se si vuole che i numeri siano trattati in maniera speciale, si deve +specificare l'opzione da riga di comando +@option{--non-decimal-data}; +@pxref{Dati non decimali}.) +Se si devono gestire dati ottali o esadecimali, +si pu@`o usare la funzione @code{strtonum()} +(@pxref{Funzioni per stringhe}) +per convertire i dati in numeri. +La maggior parte delle volte, le costanti ottali o esadecimali si usano quando +si lavora con le funzioni predefinite di manipolazione di bit; +si veda @ref{Funzioni a livello di bit} +per maggiori informazioni. + +Diversamente da alcune tra le prime implementazioni di C, @samp{8} e @samp{9} +non sono cifre valide nelle costanti ottali. Per esempio, @command{gawk} +tratta @samp{018} come un 18 decimale: + +@example +$ @kbd{gawk 'BEGIN @{ print "021 @`e", 021 ; print 018 @}'} +@print{} 021 @`e 17 +@print{} 18 +@end example + +@cindex modalit@`a compatibile di (@command{gawk}), numeri ottali +@cindex numeri ottali nella modalit@`a compatibile di (@command{gawk}) +@cindex modalit@`a compatibile di (@command{gawk}), numeri esadecimali +@cindex numeri esadecimali nella modalit@`a compatibile di (@command{gawk}) +@cindex compatibile, modalit@`a (@command{gawk}), numeri ottali +@cindex compatibile, modalit@`a (@command{gawk}), numeri esadecimali +Le costanti ottali ed esadecimali nel codice sorgente sono un'estensione di +@command{gawk}. Se @command{gawk} @`e in modalit@`a compatibile +(@pxref{Opzioni}), +non sono disponibili. + +@sidebar La base di una costante non influisce sul suo valore + +Una volta che una costante numerica @`e stata +convertita internamente in un numero [decimale], +@command{gawk} non considera pi@`u +la forma originale della costante; viene sempre usato il valore +interno. Questo ha delle precise conseguenze per la conversione dei +numeri in stringhe: + +@example +$ @kbd{gawk 'BEGIN @{ printf "0x11 vale <%s>\n", 0x11 @}'} +@print{} 0x11 vale <17> +@end example +@end sidebar + +@node Costanti come espressioni regolari +@subsubsection Costanti fornite tramite espressioni regolari + +@cindex @dfn{regexp}, costanti +@cindex costanti @dfn{regexp} +@cindex @code{~} (tilde), operatore @code{~} +@cindex tilde (@code{~}), operatore @code{~} +@cindex @code{!} (punto esclamativo), operatore @code{!~} +@cindex punto esclamativo (@code{!}), operatore @code{!~} +Una @dfn{costante regexp} @`e la descrizione di un'espressione regolare +delimitata +da barre, come @code{@w{/^inizio e fine$/}}. La maggior parte delle +@dfn{regexp} usate nei programmi @command{awk} sono costanti, ma gli operatori +di confronto @samp{~} e @samp{!~} possono confrontare anche @dfn{regexp} +calcolate o dinamiche (che tipicamente sono solo stringhe ordinarie o +variabili che contengono un'espressione regolare, ma potrebbero anche essere +espressioni pi@`u complesse). + +@node Usare le costanti @dfn{regexp} +@subsection Usare espressioni regolari come costanti + +Le costanti @dfn{regexp} sono costituite da testo che descrive un'espressione +regolare, racchiusa fra barre (come p.e. @code{/la +risposta/}). +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} tratta del comportamento di tali costanti in +POSIX @command{awk} e in @command{gawk}, e prosegue descrivendo le +@dfn{costanti @dfn{regexp} fortemente tipizzate}, che sono +un'estensione @command{gawk}. + +@menu +* Costanti @dfn{regexp} normali:: Costanti @dfn{regexp} normali in + @command{awk}. +* Costanti @dfn{regexp} forti:: Costanti @dfn{regexp} fortemente tipizzate. +@end menu + +@node Costanti @dfn{regexp} normali +@subsubsection Costanti @dfn{regexp} normali in @command{awk}. + +@cindex angolo buio, costanti @dfn{regexp} +Quand'@`e usata a destra degli operatori @samp{~} o @samp{!~}, +una costante @dfn{regexp} rappresenta semplicemente l'espressione regolare che +dev'essere confrontata. Comunque, le costanti @dfn{regexp} (come @code{/pippo/}) +possono essere usate come semplici espressioni. +Quando una +costante @dfn{regexp} compare da sola, ha lo stesso significato di quando +compare in un criterio di ricerca (cio@`e @samp{($0 ~ /pippo/)}). +@value{DARKCORNER} +@xref{Espressioni come criteri di ricerca}. +Ci@`o vuol dire che i due frammenti di codice seguenti: + +@example +if ($0 ~ /barfly/ || $0 ~ /camelot/) + print "trovato" +@end example + +@noindent +e: + +@example +if (/barfly/ || /camelot/) + print "trovato" +@end example + +@noindent +sono esattamente equivalenti. +Una conseguenza piuttosto bizzarra di questa regola @`e che la seguente +espressione booleana @`e valida, ma non fa quel che probabilmente l'autore +si aspettava: + +@example +# Notare che /pippo/ @`e alla @emph{sinistra} della ~ +if (/pippo/ ~ $1) print "trovato pippo" +@end example + +@c @cindex automatic warnings +@c @cindex warnings, automatic +@cindex @command{gawk}, costanti @dfn{regexp} e +@cindex costanti @dfn{regexp}, in @command{gawk} +@noindent +Questo codice ``ovviamente'' intende verificare se @code{$1} contiene +l'espressione regolare @code{/pippo/}. Ma in effetti l'espressione +@samp{/pippo/ ~ $1} significa realmente @samp{($0 ~ /pippo/) ~ $1}. In altre +parole, prima confronta il record in input con l'espressione regolare +@code{/pippo/}. Il risultato @`e zero o uno, a seconda che il confronto dia esito +positivo o negativo. Questo risultato +@`e poi confrontato col primo campo nel record. +Siccome @`e improbabile che qualcuno voglia mai fare realmente questo genere di +test, @command{gawk} emette un avvertimento quando vede questo costrutto in +un programma. +Un'altra conseguenza di questa regola @`e che l'istruzione di assegnamento: + +@example +confronta = /pippo/ +@end example + +@noindent +assegna zero o uno alla variabile @code{confronta}, a seconda +del contenuto del record in input corrente. + +@cindex differenze tra @command{awk} e @command{gawk}, costanti @dfn{regexp} +@cindex angolo buio, costanti @dfn{regexp}, come argomenti a funzioni definite dall'utente +@cindexgawkfunc{gensub} +@cindexawkfunc{sub} +@cindexawkfunc{gsub} +Le espressioni regolari costanti possono essere usate anche come primo +argomento delle +funzioni @code{gensub()}, @code{sub()}, e @code{gsub()}, come secondo argomento +della funzione @code{match()}, +e come terzo argomento delle funzioni @code{split()} e @code{patsplit()} +(@pxref{Funzioni per stringhe}). +Le moderne implementazioni di @command{awk}, incluso @command{gawk}, permettono +di usare come terzo argomento di @code{split()} una costante @dfn{regexp}, ma +alcune implementazioni pi@`u vecchie non lo consentono. +@value{DARKCORNER} +Poich@'e alcune funzioni predefinite accettano costanti @dfn{regexp} come +argomenti, pu@`o generare confusione l'uso di costanti @dfn{regexp} come +argomenti di funzioni definite dall'utente +(@pxref{Funzioni definite dall'utente}). Per esempio: + +@example +function mysub(modello, sostituzione, stringa, globale) +@{ + if (globale) + gsub(modello, sostituzione, stringa) + else + sub(modello, sostituzione, stringa) + return stringa +@} + +@{ + @dots{} + text = "salve! salve a te!" + mysub(/salve/, "ciao", text, 1) + @dots{} +@} +@end example + +@c @cindex automatic warnings +@c @cindex warnings, automatic +In quest'esempio, il programmatore vuol passare una costante @dfn{regexp} alla +funzione definita dall'utente @code{mysub()}, che a sua volta la passa o a +@code{sub()} o a @code{gsub()}. Comunque, quel che realmente succede @`e che +al parametro @code{modello} @`e assegnato un valore di uno o zero, a seconda +che @code{$0} corrisponda a @code{/salve/} o no. +@command{gawk} emette un avvertimento quando vede una costante @dfn{regexp} +usata come parametro di una funzione definita dall'utente, poich@'e +passare un valore vero/falso in questo modo probabilmente non @`e quello che +si intendeva fare. + +@node Costanti @dfn{regexp} forti +@subsubsection Costanti @dfn{regexp} fortemente tipizzate + +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} descrive una funzionalit@`a specifica di @command{gawk}. + +Come visto +@iftex +nella +@end iftex +@ifnottex +in +@end ifnottex +@ifdocbook +@value{SECTION} +@end ifdocbook +precedente, +le costanti @dfn{regexp} (@code{/@dots{}/}) hanno uno strano posto nel +linguaggio @command{awk}. In molti contesti, si comportano come +un'espressione: +@samp{$0 ~ /@dots{}/}. In altri contesti, denotano solo una @dfn{regexp} da +individuare. In nessun caso esse sono davvero ``cittadine di serie A'' del +linguaggio. Ovvero, non @`e possibile definire una variabile scalare il cui +tipo sia ``@dfn{regexp}'' nello stesso senso in cui si pu@`o definire una +variabile che sia un numero o una stringa: + +@example +num = 42 @ii{Variabile numerica} +str = "hi" @ii{Variabile di tipo stringa} +re = /pippo/ @ii{Errore!} re @ii{@`e il risultato di} $0 ~ /pippo/ +@end example + +Per alcuni casi di uso pi@`u avanzati, +sarebbe bello poter avere costanti @dfn{regexp} che sono +@dfn{fortemente tipizzate}; in altre parole, che sostituiscono +una @dfn{regexp} utile per effettuare dei confronti, +e non una semplice espressione regolare. + +@command{gawk} prevede questa funzionalit@`a. Un'espressione regolare +fortemente tipizzata @`e molto simile a un'espressione regolare normale, +tranne per il fatto di essere preceduta dal simbolo @samp{@@}: + +@example +re = @@/foo/ @ii{variabile @dfn{regexp} fortemente tipizzata} +@end example + +Le variabili @dfn{regexp} fortemente tipizzate @emph{non possono} essere +usate in ogni istruzione in cui compare un'espressione regolare normale. +perch@'e ci@`o renderebbe il linguaggio ancora pi@`u fuorviante. +Queste espressioni possono essere usate solo in alcuni contesti: + +@itemize @bullet +@item +Sul lato destro degli operatori @samp{~} e @samp{!~}: +@samp{qualche_variabile ~ @@/foo/} +(@pxref{Uso di @dfn{regexp}}). + +@item +Nella parte @code{case} di un'istruzione @code{switch} +(@pxref{Istruzione switch}). + +@item +Come argomento in una delle funzioni predefinite che possono utilizzare +costanti @dfn{regexp}: +@code{gensub()}, +@code{gsub()}, +@code{match()}, +@code{patsplit()}, +@code{split()} +e +@code{sub()} +(@pxref{Funzioni per stringhe}). + +@item +Come parametro in una chiamata a una funzione definita dall'utente +(@pxref{Funzioni definite dall'utente}). + +@item +Sul lato destro di un assegnamento di variabile: +@samp{qualche_variabile = @@/foo/}. +In tal caso, @code{qualche_variabile} @`e di tipo @dfn{regexp}. +Inoltre, @code{qualche_variabile} +pu@`o essere usata con gli operatori @samp{~} e @samp{!~}, passata a una +delle funzioni predefinite sopra elencate o passata come parametro +a una funzione definita dall'utente. +@end itemize + +Si pu@`o usare la funzione predefinita @code{typeof()} +(@pxref{Funzioni per i tipi}) +per determinare se un parametro passato a una funzione +@`e una variabile di tipo @dfn{regexp}. + +La vera efficacia di questa funzionalit@`a consiste nella capacit@`a di creare +variabili il cui tipo @`e @dfn{regexp}. Tali variabili possono essere passate +a funzioni definite dall'utente, senza gli inconvenenti che si hanno usando +espressioni regolari calcolate, a partire da stringhe o da costanti di tipo +stringa. Queste variabili possono anche essere passate utilizzando chiamate +indirette a funzioni (@pxref{Chiamate indirette}) e alle funzioni predefinite +che accettano costanti di tipo @dfn{regesp}. + +Quando sono usate per effettuare conversioni numeriche, le variabili +@dfn{regexp} fortemente tipizzate vengono convertite alla cifra zero. +Quando sono usate per effettuare conversioni a stringhe, vengono convertite +al valore di stringa del testo della @dfn{regexp} originale. + +@node Variabili +@subsection Variabili + +@cindex variabili definite dall'utente +@cindex definite dall'utente, variabili +Le @dfn{variabili} consentono di memorizzare valori in un certo punto di un +programma, per usarli pi@`u tardi in un'altra parte del programma. Le variabili +possono essere gestite interamente all'interno del testo del programma, ma +ad esse possono essere assegnati valori sulla riga di comando, in fase di +invocazione di @command{awk}. + +@menu +* Usare variabili:: Usare variabili nei propri programmi. +* Opzioni di assegnamento:: Impostare variabili dalla riga di + comando, e un sommario della sintassi + della riga di comando. + Questo @`e un metodo di input avanzato. +@end menu + +@node Usare variabili +@subsubsection Usare variabili in un programma + +Le variabili permettono di dare nomi ai valori e di far riferimento ad essi in +un secondo momento. Alcune variabili sono gi@`a state usate in molti degli +esempi. +Il nome di una variabile dev'essere una sequenza di lettere, cifre o trattini +bassi, e non deve iniziare con una cifra. +Qui, una @dfn{lettera} @`e una qualsiasi delle 52 lettere maiuscole e minuscole +dell'alfabeto inglese. Altri caratteri che possono essere definiti come +lettere in localizzazioni non inglesi non sono validi nei nomi di variabile. +Il maiuscolo o minuscolo sono significativi nei nomi di variabile; +@code{a} e @code{A} sono variabili diverse. + +Un nome di variabile @`e un'espressione valida in se stessa; rappresenta il +valore corrente della variabile. I valori delle variabili possono essere +modificati tramite @dfn{operatori di assegnamento}, @dfn{operatori di +incremento} e @dfn{operatori di decremento} +(@xref{Operatori di assegnamento}). +Inoltre, le funzioni @code{sub()} e @code{gsub()} possono cambiare il valore +di una variabile e le funzioni +@code{match()}, @code{split()}, e @code{patsplit()} possono cambiare il +contenuto dei loro parametri che sono +costituiti da vettori +(@pxref{Funzioni per stringhe}). + +@cindex variabili, predefinite +@cindex variabili, inizializzazione +Alcune variabili hanno un significato speciale predefinito, come @code{FS} +(il separatore di campo) e @code{NF} (il numero di campi nel record di input +corrente). @xref{Variabili predefinite} per un elenco delle variabili +predefinite. Queste variabili predefinite possono essere usate e possono +ricevere assegnamenti come tutte le altre variabili, ma i loro valori sono +anche usati o cambiati automaticamente da @command{awk}. Tutti i nomi delle +variabili predefinite sono in caratteri maiuscoli. + +Alle variabili in @command{awk} possono essere assegnati valori numerici o +valori di stringa. Il tipo di valore che una variabile contiene pu@`o cambiare +durante la vita di un programma. Per default, le variabili sono inizializzate +alla stringa nulla, che vale zero se viene convertita in un numero. Non c'@`e +alcuna +necessit@`a di inizializzare esplicitamente una variabile in @command{awk}, +come invece occorre fare in C e nella maggior parte dei linguaggi +tradizionali. + +@node Opzioni di assegnamento +@subsubsection Assegnare una variabile dalla riga di comando +@cindex variabili, assegnare da riga di comando +@cindex riga di comando, variabili@comma{} assegnare da + +Si pu@`o impostare qualsiasi variabile @command{awk} includendo un +@dfn{assegnamento di variabile} tra gli argomenti sulla riga di comando quando +viene invocato @command{awk} (@pxref{Altri argomenti}). +Tale assegnamento ha la seguente forma: + +@example +@var{variabile}=@var{testo} +@end example + +@cindex @option{-v}, opzione +@noindent +Con questo assegnamento, una variabile viene impostata o all'inizio +dell'esecuzione di @command{awk} o tra la lettura di un file in input e il +successivo file in input. +Quando l'assegnamento @`e preceduto dall'opzione @option{-v}, +come nel seguente esempio: + +@example +-v @var{variabile}=@var{testo} +@end example + +@noindent +la variabile @`e impostata proprio all'inizio, ancor prima che sia eseguita la +regola @code{BEGIN}. L'opzione @option{-v} e il suo assegnamento +deve precedere tutti gli argomenti @value{FN}, e anche il testo del programma. +(@xref{Opzioni} per maggiori informazioni sull'opzione +@option{-v}.) +In alternativa, l'assegnamento di variabile @`e effettuata in un momento +determinato +dalla posizione dell'opzione tra gli argomenti "file in input", cio@`e dopo +l'elaborazione del precedente argomento "file in input". Per esempio: + +@example +awk '@{ print $n @}' n=4 inventory-shipped n=2 mail-list +@end example + +@noindent +stampa il valore del campo numero @code{n} per tutti i record in input. Prima +che venga letto il primo file, la riga di comando imposta la variabile @code{n} +al valore quattro. Questo fa s@`{@dotless{i}} che venga stampato il quarto campo delle righe +del file @file{inventory-shipped}. Dopo la fine del primo file, ma prima +che inizi il secondo file, @code{n} viene impostato a due, e quindi poi +viene stampato il secondo campo delle righe di @file{mail-list}: + +@example +$ @kbd{awk '@{ print $n @}' n=4 inventory-shipped n=2 mail-list} +@print{} 15 +@print{} 24 +@dots{} +@print{} 555-5553 +@print{} 555-3412 +@dots{} +@end example + +@cindex angolo buio, argomenti da riga di comando +Gli argomenti da riga di comando sono resi disponibili dal programma +@command{awk} nel vettore @code{ARGV} per poter essere esaminati esplicitamente +(@pxref{ARGC e ARGV}). +@command{awk} elabora i valori degli assegnamenti da riga di comando per +sequenze di protezione +(@pxref{Sequenze di protezione}). +@value{DARKCORNER} + +@node Conversione +@subsection Conversione di stringhe e numeri + +Le conversioni di numeri in stringhe e di stringhe in numeri sono generalmente +semplici. Ci possono essere delle sottigliezze che bisogna tenere presenti; +questa @value{SECTION} tratta di quest'importante sfaccettatura di @command{awk}. + +@menu +* Stringhe e numeri:: Come @command{awk} converte tra + stringhe e numeri. +* Localizzazione e conversioni:: Come la localizzazione pu@`o influire + sulle conversioni. +@end menu + +@node Stringhe e numeri +@subsubsection Come @command{awk} converte tra stringhe e numeri + +@cindex conversione da stringhe a numeri +@cindex stringhe, conversione +@cindex numeri, conversione in stringhe +@cindex conversione da numeri a stringhe +Le stringhe sono convertite in numeri e i numeri sono convertiti in stringhe, +se il contesto del programma @command{awk} lo richiede. Per esempio, se il +valore di @code{pippo} o @code{pluto} nell'espressione @samp{pippo + pluto} +@`e una stringa, viene convertita in un numero prima di eseguire l'addizione. +Se in una concatenazione di stringhe ci sono valori numerici, questi sono +convertiti in stringhe. Si consideri il seguente esempio: + +@example +due = 2; tre = 3 +print (due tre) + 4 +@end example + +@noindent +Stampa il valore (numerico) di 27. I valori numerici delle +variabili @code{due} e @code{tre} sono convertiti in stringhe e +concatenati insieme. La stringa risultante @`e riconvertita nel +numero 23, al quale poi viene aggiunto 4. + +@cindex stringhe nulle, conversione da tipo numerico a tipo stringa +@cindex conversione di tipo variabile +@cindex variabile, conversione di tipo +Se, per qualche ragione, si vuole forzare la conversione di un numero in +una stringa, basta concatenare a quel numero la stringa nulla, @code{""}. +Per forzare la conversione di una stringa in un numero, basta aggiungere zero +a quella stringa. Una stringa viene convertita in un numero interpretando +qualsiasi prefisso numerico della stringa come numero: +@code{"2.5"} si converte in 2.5, @code{"1e3"} si converte in 1000, e +@code{"25fix"} ha un valore numerico di 25. +Le stringhe che non possono essere interpretate come numeri validi vengono +convertite al valore zero. + +@cindex @code{CONVFMT}, variabile +Il modo esatto in cui i numeri sono convertiti in stringhe @`e controllato dalla +variabile predefinita di @command{awk} @code{CONVFMT} +(@pxref{Variabili predefinite}). I numeri vengono convertiti usando la +funzione @code{sprintf()} +con @code{CONVFMT} come specificatore di formato +(@pxref{Funzioni per stringhe}). + +Il valore di default di @code{CONVFMT} @`e @code{"%.6g"}, che crea un valore con +un massimo di sei cifre significative. Per alcune applicazioni potrebbe essere +opportuno cambiare questo valore per ottenere una maggiore precisione. +Sulla maggior parte delle macchine moderne +normalmente bastano 17 cifre per esprimere esattamente il valore di un numero +in virgola mobile.@footnote{Per casi eccezionali possono essere richieste fino +a 752 cifre (!), non sembra che sia il caso di preoccuparsene qui.} + +@cindex angolo buio, variabile @code{CONVFMT} +Si possono avere strani risultati se si imposta @code{CONVFMT} a una stringa +che non indica a @code{sprintf()} come formattare i numeri in virgola mobile +in un modo utile. Per esempio, se ci si dimentica la @samp{%} nel formato, +@command{awk} converte tutti i numeri alla stessa stringa costante. + +Come caso particolare, per un numero intero, il risultato della conversione +a una stringa @`e @emph{sempre} un numero intero, indipendentemente da quale +sia il valore di @code{CONVFMT}. Dato il seguente fammento di codice: + +@example +CONVFMT = "%2.2f" +a = 12 +b = a "" +@end example + +@noindent +@code{b} ha valore @code{"12"}, non @code{"12.00"}. +@value{DARKCORNER} + +@sidebar @command{awk} prima di POSIX usava @code{OFMT} per la conversione di stringhe +@cindex POSIX @command{awk}, variabile @code{OFMT} e +@cindex @code{OFMT}, variabile +@cindex portabilit@`a, nuovo @command{awk} vs.@: vecchio @command{awk} +@cindex @command{awk}, nuovo vs.@: vecchio, variabile @code{OFMT} +Prima dello standard POSIX, @command{awk} usava il valore di @code{OFMT} per +convertire i numeri in stringhe. @code{OFMT} specifica il formato di output da +usare per la stampa dei numeri con @code{print}. @code{CONVFMT} fu introdotto +per separare la semantica della conversione dalla semantica della stampa. Sia +@code{CONVFMT} che @code{OFMT} hanno lo stesso valore di dafault: +@code{"%.6g"}. Nella stragrande maggioranza dei casi, i vecchi programmi di +@command{awk} non cambiano questo comportamento. +@xref{Print} per maggiori informazioni sull'istruzione @code{print}. +@end sidebar + +@node Localizzazione e conversioni +@subsubsection Le localizzazioni possono influire sulle conversioni + +Il luogo dove si @`e pu@`o avere importanza quando si tratta di convertire numeri e +stringhe. La lingua e i caratteri---la @dfn{localizzazione}---possono +influire sui formati numerici. In particolare, per i programmi @command{awk}, +influiscono sui caratteri separatore decimale e separatore delle migliaia. +La localizzazione @code{"C"}, e la maggior parte delle localizzazioni inglesi, +usano il punto (@samp{.}) come separatore decimale e non prevedono un +separatore delle +migliaia. Tuttavia, molte (se non la maggior parte) delle localizzazioni +europee e non inglesi usano la virgola (@samp{,}) come separatore dei decimali. +Le localizzazioni europee spesso usano o lo spazio o il punto come separatore +delle migliaia, all'occorrenza. + +@cindex angolo buio, carattere di separazione dei decimali nelle localizzazioni +Lo standard POSIX prevede che @command{awk} usi sempre il punto come separatore +dei decimali nel codice sorgente del programma @command{awk}, e per +gli assegnamenti di variabile da riga di comando (@pxref{Altri argomenti}). +Tuttavia, nell'interpretazione dei dati in input, per l'output di +@code{print} e @code{printf}, e per la conversione da numeri a stringhe, +viene usato il +separatore decimale locale. @value{DARKCORNER} In ogni caso, i numeri nel +codice sorgente e nei dati di input non possono avere un separatore delle +migliaia. Di seguito sono riportati alcuni esempi che illustrano la differenza +di comportamento, su un sistema GNU/Linux: + +@example +$ @kbd{export POSIXLY_CORRECT=1} @ii{Forzare aderenza a standard POSIX} +$ @kbd{gawk 'BEGIN @{ printf "%g\n", 3.1415927 @}'} +@print{} 3.14159 +$ @kbd{LC_ALL=en_DK.utf-8 gawk 'BEGIN @{ printf "%g\n", 3.1415927 @}'} +@print{} 3,14159 +$ @kbd{echo 4,321 | gawk '@{ print $1 + 1 @}'} +@print{} 5 +$ @kbd{echo 4,321 | LC_ALL=en_DK.utf-8 gawk '@{ print $1 + 1 @}'} +@print{} 5,321 +@end example + +@noindent +La localizzazione @code{en_DK.utf-8} @`e per l'inglese in Danimarca, dove +le virgole fungono da separatore decimale. Nella localizzazione @code{"C"} +normale, @command{gawk} tratta @samp{4,321} come 4, mentre nella localizzazione +danese @`e trattato come numero completo comprendente la parte frazionaria, +4.321. + +Alcune delle prime versioni di @command{gawk} si conformavano completamente con +quest'aspetto dello standard. Tuttavia, molti utenti di localizzazioni non +inglesi si lamentavano di questo comportamento, perch@'e i loro dati usavano il +punto come separatore decimale, per cui fu ripristinato il comportamento di +default che usava il punto come carattere di separazione decimale. Si pu@`o +usare l'opzione @option{--use-lc-numeric} (@pxref{Opzioni}) per forzare +@command{gawk} a usare il carattere separatore decimale della localizzazione. +(@command{gawk} usa il separatore decimale della localizzazione anche quando +@`e in modalit@`a POSIX, o con l'opzione @option{--posix} o con la variabile +d'ambiente @env{POSIXLY_CORRECT}, come appena visto.) + +@ref{table-locale-affects} descrive i casi in cui si usa il separatore decimale +locale e quando si usa il punto. Alcune di queste funzionalit@`a non sono state +ancora descritte. + +@float Tabella,table-locale-affects +@caption{Separatore decimale locale o punto} +@multitable @columnfractions .15 .25 .45 +@headitem Funzione @tab Default @tab @option{--posix} o @option{--use-lc-numeric} +@item @code{%'g} @tab Usa la localizzazione @tab Usa la localizzazione +@item @code{%g} @tab Usa il punto @tab Usa la localizzazione +@item Input @tab Usa il punto @tab Usa la localizzazione +@item @code{strtonum()} @tab Usa il punto @tab Usa la localizzazione +@end multitable +@end float + +Infine, gli standard ufficiali correnti e la rappresentazione dei numeri +in virgola mobile dello standard IEEE possono avere un effetto insolito ma +importante sul modo in cui @command{gawk} converte alcuni valori di stringa +speciali in +numeri. I dettagli sono illustrati in @ref{Problemi virgola mobile POSIX}. + +@node Tutti gli operatori +@section Operatori: fare qualcosa coi valori + +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} introduce gli @dfn{operatori} che fanno uso +dei valori forniti da costanti e variabili. + +@menu +* Operatori aritmetici:: Operazioni aritmetiche (@samp{+}, @samp{-}, + etc.) +* Concatenazione:: Concatenazione di stringhe. +* Operatori di assegnamento:: Cambiare il valore di una variabile o di un + campo. +* Operatori di incremento:: Incrementare il valore numerico di una + variabile. +@end menu + +@node Operatori aritmetici +@subsection Operatori aritmetici +@cindex aritmetici, operatori +@cindex operatori aritmetici +@c @cindex addition +@c @cindex subtraction +@c @cindex multiplication +@c @cindex division +@c @cindex remainder +@c @cindex quotient +@c @cindex exponentiation + +Il linguaggio @command{awk} usa i comuni operatori aritmetici nella valutazione +delle espressioni. Tutti questi operatori aritmetici seguono le normali regole +di precedenza e funzionano come ci si aspetta. + +Il seguente esempio usa un file chiamato @file{grades}, che contiene +una lista di nomi di studenti e anche i voti di tre verifiche per ogni studente +(@`e una piccola classe): + +@example +Pat 100 97 58 +Sandy 84 72 93 +Chris 72 92 89 +@end example + +@noindent +Questo programma prende il file @file{grades} e stampa la media +dei voti: + +@example +$ @kbd{awk '@{ sum = $2 + $3 + $4 ; avg = sum / 3} +> @kbd{print $1, avg @}' grades} +@print{} Pat 85 +@print{} Sandy 83 +@print{} Chris 84.3333 +@end example + +La lista seguente elenca gli operatori aritmetici in @command{awk}, +in ordine di precedenza, da quella pi@`u alta a quella pi@`u bassa: + +@table @code +@cindex estensioni comuni, operatore @code{**} +@cindex POSIX @command{awk}, operatori aritmetici e +@item @var{x} ^ @var{y} +@itemx @var{x} ** @var{y} +Elevamento a potenza; @var{x} elevato alla potenza @var{y}. @samp{2 ^ 3} +ha il valore otto; la sequenza di caratteri @samp{**} @`e equivalente a +@samp{^}. @value{COMMONEXT} + +@item - @var{x} +Negazione. + +@item + @var{x} +Pi@`u unario; l'espressione @`e convertita in un numero. + +@item @var{x} * @var{y} +Moltiplicazione. + +@cindex risoluzione di problemi, divisione +@cindex problemi, risoluzione di, divisione +@cindex divisione +@item @var{x} / @var{y} +Divisione; poich@'e tutti i numeri in @command{awk} sono numeri in virgola +mobile, il risultato @emph{non} @`e arrotondato all'intero---@samp{3 / 4} ha il +valore di 0.75. (Un errore comune, specialmente tra i programmatori in C, @`e +quello di dimenticare che @emph{tutti} i numeri in @command{awk} sono in virgola mobile, +e che la divisione di costanti rappresentate da numeri interi produce un +numero reale, non un numero intero.) + +@item @var{x} % @var{y} +Resto della divisione; subito dopo questa lista, l'argomento viene +ulteriormente dettagliato. + +@item @var{x} + @var{y} +Addizione. + +@item @var{x} - @var{y} +Sottrazione. +@end table + +Il pi@`u e il meno unari hanno la stessa precedenza, +gli operatori di moltiplicazione hanno tutti la stessa precedenza, e +l'addizione e la sottrazione hanno la stessa precedenza. + +@cindex differenze tra @command{awk} e @command{gawk}, operazione di modulo-troncamento +@cindex modulo-troncamento, operazione di +Quando si calcola il resto di @samp{@var{x} % @var{y}}, +il quoziente @`e troncato all'intero e +moltiplicato per @var{y}. Questo risultato @`e sottratto da @var{x}; +quest'operazione @`e nota anche come ``modulo''. La seguente +relazione @`e sempre verificata: + +@example +b * int(a / b) + (a % b) == a +@end example + +Un possibile effetto indesiderato di questa definizione di resto @`e che +@samp{@var{x} % @var{y}} sia negativo se @var{x} @`e negativo. Cos@`{@dotless{i}}: + +@example +-17 % 8 = -1 +@end example + +In altre implementazioni di @command{awk} il segno del resto +pu@`o essere dipendente dalla macchina. +@c FIXME !!! what does posix say? + +@cindex portabilit@`a, operatore @code{**} +@cindex @code{*} (asterisco), operatore @code{**} +@cindex asterisco (@code{*}), operatore @code{**} +@quotation NOTA +Lo standard POSIX specifica solo l'uso di @samp{^} +per l'elevamento a potenza. +Per garantire la massima portabilit@`a @`e meglio non usare l'operatore @samp{**}. +@end quotation + +@node Concatenazione +@subsection Concatenazione di stringhe +@cindex Kernighan, Brian +@quotation +@i{Allora ci era sembrata una buona idea.} +@author Brian Kernighan +@end quotation + +@cindex operatori di stringa +@cindex stringa, operatori di +@cindex concatenare +C'@`e una sola operazione di stringa: la concatenazione. Non ha un operatore +specifico per rappresentarla. Piuttosto, la concatenazione @`e effettuata +scrivendo le espressioni l'una vicino all'altra, senza alcun operatore. +Per esempio: + +@example +$ @kbd{awk '@{ print "Campo numero uno: " $1 @}' mail-list} +@print{} Campo numero uno: Amelia +@print{} Campo numero uno: Anthony +@dots{} +@end example + +Senza lo spazio nella costante stringa dopo @samp{:}, la riga +rimane unita. Per esempio: + +@example +$ @kbd{awk '@{ print "Campo numero uno:" $1 @}' mail-list} +@print{} Campo numero uno:Amelia +@print{} Campo numero uno:Anthony +@dots{} +@end example + +@cindex risoluzione di problemi, concatenazione di stringhe +@cindex problemi, risoluzione di, concatenazione di stringhe +Poich@'e la concatenazione di stringhe non ha un operatore esplicito, @`e spesso +necessario assicurarsi che venga effettuata al momento giusto usando le +parentesi per racchiudere gli elementi da concatenare. Per esempio, ci si +potrebbe aspettare che il +seguente fammento di codice concateni @code{nome} e @code{file}: + +@example +nome = "nome" +file = "file" +print "qualcosa di significativo" > nome file +@end example + +@cindex Brian Kernighan, @command{awk} di +@cindex @command{mawk}, programma di utilit@`a +@cindex programma di utilit@`a @command{mawk} +@noindent +Questo produce un errore di sintassi in alcune versioni di +@command{awk} per Unix.@footnote{Pu@`o capitare che BWK +@command{awk}, @command{gawk} e @command{mawk} lo interpretino nel modo giusto, +ma non ci si dovrebbe fare affidamento.} +@`E necessario usare la seguente sintassi: + +@example +print "qualcosa di significativo" > (nome file) +@end example + +@cindex ordine di valutazione, concatenazione +@cindex valutazione, ordine di, concatenazione +@cindex effetti collaterali +Si dovrebbero usare le parentesi attorno alle concatenazioni in tutti i +contesti non comuni, come, per esempio, sul lato destro di @samp{=}. +Bisogna stare attenti +al tipo di espressioni usate nella concatenazione di stringhe. In particolare, +l'ordine di valutazione di espressioni usate per la concatenazione non @`e +definita nel linguaggio @command{awk}. Si consideri quest'esempio: + +@example +BEGIN @{ + a = "Non" + print (a " " (a = "v'allarmate")) +@} +@end example + +@noindent +Non @`e definito se il secondo assegnamento ad @code{a} debba avvenire +prima o dopo il recupero del valore di @code{a} per produrre il +valore concatenato. Il risultato potrebbe essere sia @samp{Non v'allarmate}, +sia @samp{v'allarmate v'allarmate}. +@c see test/nasty.awk for a worse example + +La precedenza della concatenazione, quando @`e in combinazione con altri +operatori, @`e spesso controintuitiva. Si consideri questo esempio: + +@ignore +> To: bug-gnu-utils@@gnu.org +> CC: arnold@@gnu.org +> Subject: gawk 3.0.4 bug with {print -12 " " -24} +> From: Russell Schulz <Russell_Schulz@locutus.ofB.ORG> +> Date: Tue, 8 Feb 2000 19:56:08 -0700 +> +> gawk 3.0.4 on NT gives me: +> +> prompt> cat bad.awk +> BEGIN { print -12 " " -24; } +> +> prompt> gawk -f bad.awk +> -12-24 +> +> when I would expect +> +> -12 -24 +> +> I have not investigated the source, or other implementations. The +> bug is there on my NT and DOS versions 2.15.6 . +@end ignore + +@example +$ @kbd{awk 'BEGIN @{ print -12 " " -24 @}'} +@print{} -12-24 +@end example + +Quest'esempio, ``ovviamente'' concatena @minus{}12, uno spazio, e @minus{}24. +Ma dov'@`e finito lo spazio? +La risposta sta nella combinazione di precedenze di operatori e nelle regole di +conversione automatica di @command{awk}. Per ottenere il risultato desiderato, +si deve scrivere il programma in questo modo: + +@example +$ @kbd{awk 'BEGIN @{ print -12 " " (-24) @}'} +@print{} -12 -24 +@end example + +Questo forza il trattamento, da parte di @command{awk}, del @samp{-} del +@samp{-24} come operatore unario. Altrimenti @`e analizzato in questo modo: + +@display + @minus{}12 (@code{"@ "} @minus{} 24) +@result{} @minus{}12 (0 @minus{} 24) +@result{} @minus{}12 (@minus{}24) +@result{} @minus{}12@minus{}24 +@end display + +Come si @`e detto precedentemente, +quando si usa la concatenazione insieme ad altri operatori, @`e necessario +@emph{usare le parentesi}. Altrimenti, non si pu@`o essere mai completamente +certi di quel che si ottiene. + +@node Operatori di assegnamento +@subsection Espressioni di assegnamento +@cindex operatori di assegnamento +@cindex assegnamento, operatori di +@cindex espressioni di assegnamento +@cindex @code{=} (uguale), operatore @code{=} +@cindex uguale (@code{=}), operatore @code{=} +Un @dfn{assegnamento} @`e un'espressione che memorizza un valore (generalmente +diverso da quello che la variabile aveva in precedenza) in una variabile. +Per esempio, si assegni il valore uno alla variabile @code{z}: + +@example +z = 1 +@end example + +Dopo l'esecuzione di quest'espressione, la variabile @code{z} ha il valore +uno. Qualsiasi precedente valore di @code{z} prima dell'assegnamento +viene dimenticato. + +Gli assegnamenti possono anche memorizzare valori di stringa. Il seguente +esempio memorizza +il valore @code{"questo cibo @`e buono"} nella variabile @code{messaggio}: + +@example +cosa = "cibo" +predicato = "buono" +messaggio = "questo " cosa " @`e " predicato +@end example + +@noindent +@cindex effetti collaterali, espressioni di assegnamento +Quest'esempio illustra anche la concatenazione di stringhe. +Il segno @samp{=} @`e un @dfn{operatore di assegnamento}. @`E il pi@`u semplice +fra gli operatori di assegnamento perch@'e il valore dell'operando di destra +@`e memorizzato invariato. +La maggior parte degli operatori (addizione, concatenazione e cos@`{@dotless{i}} via) non +fanno altro che calcolare un valore. Se il valore non viene poi utilizzato non c'@`e alcun +motivo per usare l'operatore. Un operatore di assegnamento @`e differente; +produce un valore; anche se poi non lo si usa, l'assegnamento svolge ancora +una funzione alterando la variabile. Chiamiamo questo +un @dfn{effetto collaterale}. + +@cindex @dfn{lvalue/rvalue} +@cindex @dfn{rvalue/lvalue} +@cindex assegnamento, operatori di, @dfn{lvalue/rvalue} +@cindex operatori di assegnamento +L'operando di sinistra non dev'essere necessariamente una variabile +(@pxref{Variabili}); pu@`o essere anche un campo +(@pxref{Cambiare i campi}) o +@iftex +un elemento di un vettore (@pxrefil{Vettori}). +@end iftex +@ifnottex +un elemento di un vettore (@pxref{Vettori}). +@end ifnottex +Questi operandi sono chiamati @dfn{lvalue}, il +che significa che possono apparire sul lato sinistro di un operatore di +assegnamento. L'operando sul lato destro pu@`o essere qualsiasi espressione; +produce un nuovo valore che l'assegnamento memorizza nella variabile, nel campo +o nell'elemento di vettore specificati. Tali valori sono chiamati +@dfn{rvalue}. + +@cindex variabili, tipi di +@`E importante notare che le variabili @emph{non} hanno dei tipi permanenti. +Il tipo di una variabile @`e semplicemente quello di qualsiasi valore le sia stato +assegnato per ultimo. Nel seguente frammento di programma, la variabile +@code{pippo} ha dapprima un valore numerico, e in seguito un valore di stringa: + +@example +pippo = 1 +print pippo +pippo = "pluto" +print pippo +@end example + +@noindent +Quando il secondo assegnamento d@`a a @code{pippo} un valore di stringa, il fatto +che avesse precedentemente un valore numerico viene dimenticato. + +Ai valori di stringa che non iniziano con una cifra viene assegnato il valore +numerico zero. Dopo l'esecuzione del seguente codice, il valore di @code{pippo} @`e +cinque: + +@example +pippo = "una stringa" +pippo = pippo + 5 +@end example + +@quotation NOTA +Usare una variabile sia come numero che come stringa pu@`o originare confusione +e denota uno stile di programmazione scadente. I due esempi precedenti +illustrano come funziona @command{awk}, @emph{non} come si dovrebbero scrivere +i programmi! +@end quotation + +Un assegnamento @`e un'espressione, per cui ha un valore: lo stesso valore che +le @`e stato assegnato. Cos@`{@dotless{i}}, @samp{z = 1} @`e un'espressione col valore uno. +Una conseguenza di ci@`o @`e che si possono scrivere pi@`u assegnamenti insieme, +come: + +@example +x = y = z = 5 +@end example + +@noindent +Quest'esempio memorizza il valore cinque in tutte e tre le variabili, +(@code{x}, @code{y} e @code{z}). +Questo perch@'e il +valore di @samp{z = 5}, che @`e cinque, @`e memorizzato in @code{y} e poi +il valore di @samp{y = z = 5}, che @`e cinque, @`e memorizzato in @code{x}. + +Gli assegnamenti possono essere usati ovunque sia prevista un'espressione. Per +esempio, @`e valido scrivere @samp{x != (y = 1)} per impostare @code{y} a +uno, e poi verificare se @code{x} @`e uguale a uno. Per@`o questo stile rende i +programmi difficili da leggere; una tale nidificazione di assegnamenti dovrebbe +essere evitata, eccetto forse in un programma usa-e-getta. + +@cindex @code{+} (pi@`u), operatore @code{+=} +@cindex pi@`u (@code{+}), operatore @code{+=} +Accanto a @samp{=}, ci sono diversi altri operatori di assegnamento che +eseguono calcoli col vecchio valore di una variabile. Per esempio, +l'operatore @samp{+=} calcola un nuovo valore aggiungendo il valore sul lato +destro al vecchio valore di una variabile. Cos@`{@dotless{i}}, il seguente assegnamento +aggiunge cinque al valore di @code{pippo}: + +@example +pippo += 5 +@end example + +@noindent +Questo @`e equivalente a: + +@example +pippo = pippo + 5 +@end example + +@noindent +Si usi la notazione che rende pi@`u chiaro il significato del programma. + +Ci sono situazioni in cui usare @samp{+=} (o qualunque operatore di +assegnamento) @emph{non} @`e la stessa cosa che ripetere semplicemente l'operando +di sinistra nell'espressione di destra. Per esempio: + +@cindex Rankin, Pat +@example +# Grazie a Pat Rankin per quest'esempio +BEGIN @{ + pippo[rand()] += 5 + for (x in pippo) + print x, pippo[x] + + pluto[rand()] = pluto[rand()] + 5 + for (x in pluto) + print x, pluto[x] +@} +@end example + +@cindex operatori di assegnamento, ordine di valutazione +@cindex assegnamento, operatori di, ordine di valutazione +@noindent +@`E praticamente certo che gli indici di @code{pluto} siano differenti, perch@'e +@code{rand()} restituisce valori differenti ogni volta che viene chiamata. +(I vettori e la funzione @code{rand()} non sono ancora stati trattati. +@iftex +@xrefil{Vettori}, +@end iftex +@ifnottex +@xref{Vettori}, +@end ifnottex +e +@ifnotdocbook +@pxref{Funzioni numeriche} +@end ifnotdocbook +@ifdocbook +@ref{Funzioni numeriche} +@end ifdocbook +per maggiori informazioni.) +Quest'esempio illustra un fatto importante riguardo agli operatori di +assegnamento: l'espressione di sinistra viene valutata @emph{una volta sola}. + +Dipende dall'implementazione stabilire quale espressione valutare per +prima, se quella di sinistra o quella di destra. +Si consideri quest'esempio: + +@example +i = 1 +a[i += 2] = i + 1 +@end example + +@noindent +Il valore di @code{a[3]} potrebbe essere sia due sia quattro. + +La @ref{table-assign-ops} elenca gli operatori di assegnamento aritmetici. In +ogni caso, l'operando di destra @`e un'espressione il cui valore @`e convertito in +un numero. + +@cindex @code{-} (meno), operatore @code{-=} +@cindex meno (@code{-}), operatore @code{-=} +@cindex @code{*} (asterisco), operatore @code{*=} +@cindex asterisco (@code{*}), operatore @code{*=} +@cindex @code{/} (barra), operatore @code{/=} +@cindex barra (@code{/}), operatore @code{/=} +@cindex @code{%} (percento), operatore @code{%=} +@cindex percento (@code{%}), operatore @code{%=} +@cindex @code{^} (circonflesso), operatore @code{^=} +@cindex circonflesso (@code{^}), operatore @code{^=} +@cindex @code{*} (asterisco), operatore @code{**=} +@cindex asterisco (@code{*}), operatore @code{**=} +@float Tabella,table-assign-ops +@caption{Operatori di assegnamento aritmetici} +@multitable @columnfractions .30 .70 +@headitem Operatore @tab Effetto +@item @var{lvalue} @code{+=} @var{incremento} @tab Aggiunge @var{incremento} al valore di @var{lvalue}. +@item @var{lvalue} @code{-=} @var{decremento} @tab Sottrae @var{decremento} dal valore di @var{lvalue}. +@item @var{lvalue} @code{*=} @var{coefficiente} @tab Moltiplica il valore di @var{lvalue} per @var{coefficiente}. +@item @var{lvalue} @code{/=} @var{divisore} @tab Divide il valore di @var{lvalue} per @var{divisore}. +@item @var{lvalue} @code{%=} @var{modulo} @tab Imposta @var{lvalue} al resto della sua divisione per @var{modulo}. +@cindex estensioni comuni, operatore @code{**=} +@cindex estensioni comuni@comma{} operatore @code{**=} +@cindex @command{awk}, linguaggio, versione POSIX +@cindex POSIX @command{awk} +@item @var{lvalue} @code{^=} @var{esponente} @tab Eleva @var{lvalue} alla potenza @var{esponente}. +@item @var{lvalue} @code{**=} @var{esponente} @tab Eleva @var{lvalue} alla potenza @var{esponente}. @value{COMMONEXT} +@end multitable +@end float + +@cindex POSIX @command{awk}, operatore @code{**=} e +@cindex portabilit@`a, operatore @code{**=} +@quotation NOTA +Soltanto l'operatore @samp{^=} @`e definito da POSIX. +Per avere la massima portabilit@`a, non usare l'operatore @samp{**=}. +@end quotation + +@sidebar Ambiguit@`a sintattiche tra @samp{/=} e le espressioni regolari +@cindex angolo buio, costanti @dfn{regexp}, operatore @code{/=} e +@cindex @code{/} (barra), operatore @code{/=}, vs. costante @dfn{regexp} @code{/=@dots{}/} +@cindex barra (@code{/}), operatore @code{/=}, vs. costante @dfn{regexp} @code{/=@dots{}/} +@cindex @dfn{regexp}, costanti, @code{/=@dots{}/}, operatore @code{/=} e + +@c derived from email from "Nelson H. F. Beebe" <beebe@math.utah.edu> +@c Date: Mon, 1 Sep 1997 13:38:35 -0600 (MDT) + +@cindex angolo buio, operatore @code{/=} vs. costante @dfn{regexp} @code{/=@dots{}/} +@cindex ambiguit@`a sintattica: operatore @code{/=} vs. costante @dfn{regexp} @code{/=@dots{}/} +@cindex sintattica, ambiguit@`a: operatore @code{/=} vs. costante @dfn{regexp} @code{/=@dots{}/} +@cindex @code{/=}, operatore, vs. costante @dfn{regexp} @code{/=@dots{}/} +C'@`e un'ambiguit@`a sintattica tra l'operatore di assegnamento @code{/=} +e le costanti @dfn{regexp} il cui primo carattere sia @samp{=}. +@value{DARKCORNER} +Questo @`e pi@`u evidente in alcune versioni commerciali di @command{awk}. +Per esempio: + +@example +$ @kbd{awk /==/ /dev/null} +@error{} awk: syntax error at source line 1 +@error{} context is +@error{} >>> /= <<< +@error{} awk: bailing out at source line 1 +@end example + +@noindent +Un espediente @`e: + +@example +awk '/[=]=/' /dev/null +@end example + +@command{gawk} non ha questo problema, e neppure lo hanno BWK @command{awk} +e @command{mawk}. +@end sidebar + +@node Operatori di incremento +@subsection Operatori di incremento e di decremento + +@cindex incremento, operatori di +@cindex operatori di decremento/incremento +Gli @dfn{operatori di incremento} e @dfn{decremento} incrementano o riducono il +valore di una variabile di uno. Un operatore di assegnamento pu@`o fare la +stessa cosa, per cui gli operatori di incremento non aggiungono funzionalit@`a +al inguaggio @command{awk}; in ogni caso, sono delle convenienti abbreviazioni +per operazioni molto comuni. + +@cindex effetti collaterali +@cindex @code{+} (pi@`u), operatore @code{++} +@cindex pi@`u (@code{+}), operatore @code{++} +@cindex effetti collaterali, operatori di decremento/incremento +L'operatore per aggiungere uno @`e @samp{++}. Pu@`o essere usato per incrementare +una variabile prima o dopo aver stabilito il suo valore. Per @dfn{preincrementare} +una variabile @code{v}, si scrive @samp{++v}. Questo aggiunge uno al valore di +@code{v}; questo nuovo valore @`e anche il valore dell'espressione. +(L'espressione di assegnamento @samp{v += 1} @`e totalmente equivalente.) +Scrivendo @samp{++} dopo la variabile si specifica un @dfn{postincremento}. +Questo incrementa il valore della variabile nello stesso modo; la differenza @`e +che il valore dell'espressione d'incremento @`e il @emph{vecchio} valore della +variabile. Cos@`{@dotless{i}}, se @code{pippo} ha il valore quattro, l'espressione +@samp{pippo++} ha il valore quattro, ma cambia il valore di @code{pippo} in cinque. +In altre parole, l'operatore restituisce il vecchio valore della variabile, ma +con l'effetto collaterale di incrementarlo. + +Il postincremento @samp{pippo++} @`e quasi come scrivere @samp{(pippo += 1) - 1}. +Non @`e perfettamente equivalente perch@'e tutti i numeri in @command{awk} sono in +virgola mobile. In virgola mobile, @samp{pippo + 1 - 1} non @`e necessariamente +uguale a @code{pippo}, ma la differenza @`e molto piccola finch@'e si ha a che +fare con numeri relativamente piccoli (inferiori a +@iftex +@math{10^{12}}). +@end iftex +@ifinfo +10e12). +@end ifinfo +@ifnottex +@ifnotinfo +10@sup{12}). +@end ifnotinfo +@end ifnottex + +@cindex @code{$} (dollaro), incrementare campi e vettori +@cindex dollaro (@code{$}), incrementare campi e vettori +I campi di un record e gli elementi di un vettore vengono incrementati +proprio come le +variabili. (Si deve usare @samp{$(i++)} quando si deve fare un riferimento a +un campo e incrementare una variabile allo stesso tempo. Le parentesi sono +necessarie a causa della precedenza dell'operatore di riferimento @samp{$}.) + +@cindex decremento, operatori di +L'operatore di decremento @samp{--} funziona proprio come @samp{++}, solo che +sottrae uno anzich@'e aggiungerlo. Come @samp{++}, si pu@`o usare prima di +@dfn{lvalue} +per predecrementare o dopo per postdecrementare. +Quel che segue @`e un sommario delle espressioni di incremento e di +decremento: + +@table @code +@cindex @code{+} (pi@`u), operatore @code{++} +@cindex pi@`u (@code{+}), operatore @code{++} +@item ++@var{lvalue} +Incrementa @var{lvalue}, restituendo il nuovo valore come +valore dell'espressione. + +@item @var{lvalue}++ +Incrementa @var{lvalue}, restituendo il @emph{vecchio} valore di @var{lvalue} +come valore dell'espressione. + +@cindex @code{-} (meno), operatore @code{--} +@cindex meno (@code{-}), operatore @code{--} +@item --@var{lvalue} +Decrementa @var{lvalue}, restituendo il nuovo valore come +valore dell'espressione. +(Quest'espressione @`e come +@samp{++@var{lvalue}}, ma invece di aggiungere, sottrae.) + +@item @var{lvalue}-- +Decrementa @var{lvalue}, restituendo il @emph{vecchio} valore di @var{lvalue} +come valore dell'espressione. +(Quest'espressione @`e come +@samp{@var{lvalue}++}, ma invece di aggiungere, sottrae.) +@end table + +@sidebar Ordine di valutazione degli operatori +@cindex precedenza +@cindex operatori, precedenza +@cindex portabilit@`a, operatori +@cindex valutazione, ordine di +@cindex Marx, Groucho +@quotation +@i{Dottore, quando faccio cos@`{@dotless{i}} mi fa male!@* +E allora non farlo!} +@author Groucho Marx +@end quotation + +@noindent +Che cosa succede con qualcosa come questo? + +@example +b = 6 +print b += b++ +@end example + +@noindent +O con qualcosa di pi@`u strano ancora? + +@example +b = 6 +b += ++b + b++ +print b +@end example + +@cindex effetti collaterali +In altre parole, quando hanno effetto i vari effetti collaterali previsti +dagli operatori col suffisso (@samp{b++})? Quando gli effetti collaterali +si verificano @`e @dfn{definito dall'implementazione}. +Per dirla diversamente, questo @`e compito di ogni specifica versione di +@command{awk}. Il risultato del primo esempio pu@`o essere 12 o 13, e del +secondo pu@`o essere 22 o 23. + +In breve, @`e sconsigliato fare cose come questa e, in ogni caso, +ogni cosa che possa incidere sulla portabilit@`a. +Si dovrebbero evitare cose come queste nei programmi. +@c You'll sleep better at night and be able to look at yourself +@c in the mirror in the morning. +@end sidebar + +@node Valori e condizioni di verit@`a +@section Valori e condizioni di verit@`a + +In certi contesti, i valori delle espressioni servono anche come +``valori di verit@`a''; cio@`e, determinano quale sar@`a la direzione che il +programma prender@`a durante la sua esecuzione. Questa +@value{SECTION} descrive come @command{awk} definisce ``vero'' e ``falso'' +e come questi valori sono confrontati. + +@menu +* Valori di verit@`a:: Cos'@`e ``vero'' e cos'@`e ``falso''. +* Tipi di variabile e confronti:: Come alle variabili si assegna il tipo e + l'effetto che questo ha sul confronto di + numeri e stringhe con @samp{<}, etc. +* Operatori booleani:: Combinare espressioni di confronto usando + operatori booleani @samp{||} (``or''), + @samp{&&} (``and'') e @samp{!} (``not''). +* Espressioni condizionali:: Le espressioni condizionali scelgono una fra + due sottoespressioni, a seconda del valore di + una terza sottoespressione. +@end menu + +@node Valori di verit@`a +@subsection Vero e falso in @command{awk} +@cindex valori di verit@`a +@cindex logico, valore, vero/falso +@cindex falso, valore logico (zero o stringa nulla) +@cindex vero, valore logico (diverso da zero e da stringa nulla) + +@cindex nulle, stringhe +Molti linguaggi di programmazione hanno una particolare rappresentazione per i +concetti di ``vero'' e ``falso.'' Questi linguaggi usano normalmente le +costanti speciali @code{true} e @code{false}, o forse i loro equivalenti +maiuscoli. +Per@`o @command{awk} @`e differente. +Prende in prestito un concetto molto semplice di vero e falso dal linguaggio +C. In @command{awk}, ogni valore numerico diverso da zero @emph{oppure} +ogni valore di stringa non vuota @`e vero. Ogni altro valore (zero o la stringa +nulla, @code{""}) @`e falso. Il seguente programma stampa @samp{Uno strano +valore di verit@`a} tre volte: + +@example +BEGIN @{ + if (3.1415927) + print "Uno strano valore di verit@`a" + if ("Ottanta e sette anni or sono") + print "Uno strano valore di verit@`a" + if (j = 57) + print "Uno strano valore di verit@`a" +@} +@end example + +@cindex angolo buio, @code{"0"} @`e effettivamente vero +C'@`e una conseguenza sorprendente della regola ``non zero o non nullo'': +la costante di stringa @code{"0"} sta effettivamente per vero, perch@'e +@`e non nulla. +@value{DARKCORNER} + +@node Tipi di variabile e confronti +@subsection Tipi di variabile ed espressioni di confronto +@quotation +@i{La Guida galattica @`e infallibile. @`E la realt@`a, spesso, a essere inesatta.} +@author Douglas Adams, @cite{Guida galattica per autostoppisti} +@end quotation +@c 2/2015: Antonio Colombo points out that this is really from +@c The Restaurant at the End of the Universe. But I'm going to +@c leave it alone. + +@cindex confronto, espressioni di +@cindex espressioni di confronto +@cindex espressioni, ricerca di corrispondenze, si veda espressioni di confronto +@cindex individuazione, espressioni di, si veda espressioni di confronto +@cindex relazionali, operatori, si veda espressioni di confronto +@cindex operatori relazionali, si veda espressioni di confronto +@cindex variabile, tipi di +@cindex variabili, tipi di, espressioni di confronto e +Diversamente che in altri linguaggi di programmazione, le variabili di +@command{awk} non hanno un tipo fisso. Possono essere sia un numero che una +stringa, a seconda del valore loro assegnato. +Vediamo ora come viene assegnato il tipo a una variabile, e come @command{awk} +le confronta. + +@menu +* Tipi di variabile:: Tipo stringa rispetto a tipo numero. +* Operatori di confronto:: Gli operatori di confronto. +* Confronto POSIX di stringhe:: Confronto tra stringhe usando le + regole POSIX. +@end menu + +@node Tipi di variabile +@subsubsection Tipo stringa rispetto a tipo numero + +Per gli elementi scalari in @command{awk} (variabili, elementi di +vettore e campi), il tipo degli stessi viene attribuito @emph{dinamicamente}. +Ci@`o significa che il tipo di un elemento pu@`o cambiare nel corso +dell'esecuzione di un programma, da @dfn{untyped} (non ancora tipizzata), +valore assunto prima che la variabile sia utilizzata,@footnote{@command{gawk} +chiama queste variabili @dfn{unassigned} (non ancora assegnate), come si +vede dall'esempio che segue.} a stringa oppure a numero, e in seguito +da stringa a numero o da numero a stringa, nel prosieguo del programma. +(@command{gawk} prevede anche degli scalari di tipo @dfn{regexp}, ma +per ora possiamo ignorarli; +@pxref{Costanti @dfn{regexp} forti}.) + +Non si pu@`o fare molto riguardo alle variabili di tipo @dfn{untyped}, +oltre a constatare che ancora non @`e stato loro attribuito un tipo. +Il seguente programma confronta la variabile @code{a} con i valori +@code{""} e @code{0}; il confronto d@`a esito positivo se alla +variabile @code{a} non @`e mai stato assegnato un valore. +L'esempio usa la funzione predefinita @code{typeof()} +(non ancora trattata; @pxref{Funzioni per i tipi}) per +visualizzare il tipo della variabile @code{a}: + +@example +$ @kbd{gawk 'BEGIN @{ print (a == "" && a == 0 ?} +> @kbd{"a non ha un tipo" : "a ha un tipo!") ; print typeof(a) @}'} +@print{} a non ha un tipo +@print{} unassigned +@end example + +Una variabile scalare diviene di tipo numerico quando le viene assegnato un +valore numerico, per mezzo di una costante numerica, o tramite un'altra +variabile scalare di tipo numerico: + +@example +$ @kbd{gawk 'BEGIN @{ a = 42 ; print typeof(a)} +> @kbd{b = a ; print typeof(b) @}'} +number +number +@end example + +Analogamente, una variabile scalare diviene di tipo stringa quando le +viene assegnato come valore una stringa, per mezzo di una costante stringa, +o tramite un'altra variabile scalare di tipo stringa: + +@example +$ @kbd{gawk 'BEGIN @{ a = "quarantadue" ; print typeof(a)} +> @kbd{b = a ; print typeof(b) @}'} +string +string +@end example + +Fin qui, tutto semplice e chiaro. Cosa succede, per@`o, quando +@command{awk} deve trattare dati forniti dall'utente? +Il primo caso da considerare @`e quello dei campi di dati in input. +Quale dovrebbe essere l'output del seguente programma? + +@example +echo ciao | awk '@{ printf("%s %s < 42\n", $1, + ($1 < 42 ? "@`e" : "non @`e")) @}' +@end example + +@noindent +Poich@'e @samp{ciao} @`e un dato di tipo alfabetico, @command{awk} pu@`o solo +effettuare un confronto di tipo stringa. Internamente, il numero @code{42} +viene convertito in @code{"42"} e vengono confrontate le due stringhe di +valore @code{"ciao"} e @code{"42"}. Questo @`e il risultato: + +@example +$ @kbd{echo ciao | awk '@{ printf("%s %s < 42\n", $1,} +> @kbd{ ($1 < 42 ? "@`e" : "non @`e")) @}'} +@print{} ciao non @`e < 42 +@end example + +Tuttavia, cosa succede quando un dato utente @emph{assomiglia} a un +numero? +Da un lato, in realt@`a, il dato in input @`e formato da alcuni caratteri, non da +valori numerici in formato binario. Ma, d'altro lato, il dato sembra +numerico, e @command{awk} dovrebbe davvero trattarlo come tale. E in effetti +questo @`e ci@`o che avviene: + +@example +$ @kbd{echo 37 | awk '@{ printf("%s %s < 42\n", $1,} +> @kbd{ ($1 < 42 ? "@`e" : "non @`e")) @}'} +@print{} 37 is < 42 +@end example + +Queste sono le regole seguite per determinare quando @command{awk} +tratta dei dati in input come numeri, e quando li considera stringhe. + +@cindex numeriche, stringhe +@cindex stringhe, numeriche +@cindex POSIX @command{awk}, stringhe numeriche e +Lo standard POSIX usa il concetto di @dfn{stringa numerica}, per dei dati +in input che appaiono essere numerici. Il @samp{37} nell'esempio precedente +@`e una stringa numerica. Quindi, qual @`e il tipo di una stringa numerica? +Risposta: numerico. + +Il tipo di una variabile @`e importante perch@'e il tipo di due variabili +determina il modo con cui le stesse vengono confrontate. +La determinazione del tipo di variabile segue queste regole: + +@itemize @value{BULLET} +@item +Una costante numerica o il risultato di un'operazione numerica ha l'attributo +@dfn{numeric}. + +@item +Una costante di stringa o il risultato di un'operazione di stringa ha +l'attributo @dfn{string}. + +@item +Campi, input tramite @code{getline}, @code{FILENAME}, elementi di +@code{ARGV}, elementi di @code{ENVIRON}, e gli elementi di un vettore +creato da @code{match()}, @code{split()} e @code{patsplit()} che sono +stringhe numeriche hanno l'attributo @dfn{strnum}.@footnote{Quindi, una +stringa numerica POSIX e una variabile tipo @dfn{strnum} di @command{gawk} +sono equivalenti.} +Altrimenti, hanno l'attributo @dfn{string}. +Anche le variabili non inizializzate hanno l'attributo @var{strnum}. + +@item +Gli attributi si trasmettono attraverso gli assegnamenti ma non vengono +cambiati da nessun uso. +@c (Although a use may cause the entity to acquire an additional +@c value such that it has both a numeric and string value, this leaves the +@c attribute unchanged.) +@c This is important but not relevant +@end itemize + +L'ultima regola @`e particolarmente importante. Nel seguente programma, +@code{a} @`e di tipo numerico, anche se viene usata in un secondo momento in +un'operazione di stringa: + +@example +BEGIN @{ + a = 12.345 + b = a " @`e un numero carino" + print b +@} +@end example + +Quando si confrontano due operandi, pu@`o essere usata sia il confronto come +stringa che il confronto numerico, a seconda degli attributi degli operandi, +secondo questa matrice simmetrica: + +@c thanks to Karl Berry, kb@cs.umb.edu, for major help with TeX tables +@tex +\centerline{ +\vbox{\bigskip % space above the table (about 1 linespace) +% Because we have vertical rules, we can't let TeX insert interline space +% in its usual way. +\offinterlineskip +% +% Define the table template. & separates columns, and \cr ends the +% template (and each row). # is replaced by the text of that entry on +% each row. The template for the first column breaks down like this: +% \strut -- a way to make each line have the height and depth +% of a normal line of type, since we turned off interline spacing. +% \hfil -- infinite glue; has the effect of right-justifying in this case. +% # -- replaced by the text (for instance, `STRNUM', in the last row). +% \quad -- about the width of an `M'. Just separates the columns. +% +% The second column (\vrule#) is what generates the vertical rule that +% spans table rows. +% +% The doubled && before the next entry means `repeat the following +% template as many times as necessary on each line' -- in our case, twice. +% +% The template itself, \quad#\hfil, left-justifies with a little space before. +% +\halign{\strut\hfil#\quad&\vrule#&&\quad#\hfil\cr + &&STRING &NUMERIC &STRNUM\cr +% The \omit tells TeX to skip inserting the template for this column on +% this particular row. In this case, we only want a little extra space +% to separate the heading row from the rule below it. the depth 2pt -- +% `\vrule depth 2pt' is that little space. +\omit &depth 2pt\cr +% This is the horizontal rule below the heading. Since it has nothing to +% do with the columns of the table, we use \noalign to get it in there. +\noalign{\hrule} +% Like above, this time a little more space. +\omit &depth 4pt\cr +% The remaining rows have nothing special about them. +STRING &&string &string &string\cr +NUMERIC &&string &numeric &numeric\cr +STRNUM &&string &numeric &numeric\cr +}}} +@end tex +@ifnottex +@ifnotdocbook +@verbatim + +---------------------------------------------- + | STRING NUMERIC STRNUM +--------+---------------------------------------------- + | +STRING | string string string + | +NUMERIC | string numeric numeric + | +STRNUM | string numeric numeric +--------+---------------------------------------------- +@end verbatim +@end ifnotdocbook +@end ifnottex +@docbook +<informaltable> +<tgroup cols="4"> +<colspec colname="1" align="left"/> +<colspec colname="2" align="left"/> +<colspec colname="3" align="left"/> +<colspec colname="4" align="left"/> +<thead> +<row> +<entry/> +<entry>STRING</entry> +<entry>NUMERIC</entry> +<entry>STRNUM</entry> +</row> +</thead> + +<tbody> +<row> +<entry><emphasis role="bold">STRING</emphasis></entry> +<entry>string</entry> +<entry>string</entry> +<entry>string</entry> +</row> + +<row> +<entry><emphasis role="bold">NUMERIC</emphasis></entry> +<entry>string</entry> +<entry>numeric</entry> +<entry>numeric</entry> +</row> + +<row> +<entry><emphasis role="bold">STRNUM</emphasis></entry> +<entry>string</entry> +<entry>numeric</entry> +<entry>numeric</entry> +</row> + +</tbody> +</tgroup> +</informaltable> + +@end docbook + +L'idea di base @`e che l'input dell'utente che appare come numerico---e +@emph{solo} l'input dell'utente---dovrebbe essere trattato come numerico, anche +se in realt@`a @`e un insieme di caratteri e quindi anche una stringa. +Cos@`{@dotless{i}}, ad esempio, la costante di stringa @w{@code{" +3.14"}}, +quando appare nel codice sorgente di un programma, +@`e una stringa---anche se sembra numerica---e non +viene @emph{mai} trattato come numero +ai fini di un confronto. + +In breve, quando un operando @`e una stringa ``pura'', come una costante di +stringa, viene effettuato un confronto di stringa. In caso contrario viene +effettuato un confronto numerico. +(La differenza principale tra un numero e uno @dfn{strnum} @`e che per gli +@dfn{strnum} @command{gawk} conserva anche il valore originale della stringa +che la variabile scalare aveva al momento in cui @`e stata letta. + +Questo punto merita di essere ulteriormente ribadito: +l'input che appare essere un numero @emph{@`e} numerico. +Tutto il resto dell'input @`e considerato essere una stringa. + +Cos@`{@dotless{i}}, la stringa in input di sei caratteri @w{@samp{ +3.14}} +riceve l'attributo @dfn{strnum}. Al contrario, la stringa di sei caratteri +@w{@code{" +3.14"}} che compaia nel testo di un programma rimane una +costante di stringa. I seguenti esempi stampano @samp{1} quando il confronto +fra due diverse costanti @`e vero, altrimenti stampano @samp{0}: + +@c 22.9.2014: Tested with mawk and BWK awk, got same results. +@example +$ @kbd{echo ' +3.14' | awk '@{ print($0 == " +3.14") @}'} @ii{Vero} +@print{} 1 +$ @kbd{echo ' +3.14' | awk '@{ print($0 == "+3.14") @}'} @ii{Falso} +@print{} 0 +$ @kbd{echo ' +3.14' | awk '@{ print($0 == "3.14") @}'} @ii{Falso} +@print{} 0 +$ @kbd{echo ' +3.14' | awk '@{ print($0 == 3.14) @}'} @ii{Vero} +@print{} 1 +$ @kbd{echo ' +3.14' | awk '@{ print($1 == " +3.14") @}'} @ii{Falso} +@print{} 0 +$ @kbd{echo ' +3.14' | awk '@{ print($1 == "+3.14") @}'} @ii{Vero} +@print{} 1 +$ @kbd{echo ' +3.14' | awk '@{ print($1 == "3.14") @}'} @ii{Falso} +@print{} 0 +$ @kbd{echo ' +3.14' | awk '@{ print($1 == 3.14) @}'} @ii{Vero} +@print{} 1 +@end example + +Per controllare il tipo di un campo in input (o di altro input immesso +dall'utente, si pu@`o usare @code{typeof()}: + +@example +$ @kbd{echo salve 37 | gawk '@{ print typeof($1), typeof($2) @}'} +@print{} string strnum +@end example + +@node Operatori di confronto +@subsubsection Operatori di confronto + +Le @dfn{espressioni di confronto} confrontano stringhe o numeri per metterli in +relazione tra di loro, come ad esempio nella relazione di uguaglianza. Sono +scritte usando @dfn{operatori di relazione}, che sono un superinsieme di quelli +in C. Sono descritti nella @ref{table-relational-ops}. + +@cindex @code{<} (parentesi acuta sinistra), operatore @code{<} +@cindex parentesi acuta sinistra (@code{<}), operatore @code{<} +@cindex @code{<} (parentesi acuta sinistra), operatore @code{<=} +@cindex parentesi acuta sinistra (@code{<}), operatore @code{<=} +@cindex @code{>} (parentesi acuta destra), operatore @code{>=} +@cindex parentesi acuta destra (@code{>}), operatore @code{>=} +@cindex @code{>} (parentesi acuta destra), operatore @code{>} +@cindex parentesi acuta destra (@code{>}), operatore @code{>} +@cindex @code{=} (uguale), operatore @code{==} +@cindex uguale (@code{=}), operatore @code{==} +@cindex @code{!} (punto esclamativo), operatore @code{!=} +@cindex punto esclamativo (@code{!}), operatore @code{!=} +@cindex @code{~} (tilde), operatore @code{~} +@cindex tilde (@code{~}), operatore @code{~} +@cindex @code{!} (punto esclamativo), operatore @code{!~} +@cindex punto esclamativo (@code{!}), operatore @code{!~} +@cindex @code{in}, operatore +@float Tabella,table-relational-ops +@caption{Operatori di relazione} +@multitable @columnfractions .23 .77 +@headitem Espressione @tab Risultato +@item @var{x} @code{<} @var{y} @tab Vero se @var{x} @`e minore di @var{y} +@item @var{x} @code{<=} @var{y} @tab Vero se @var{x} @`e minore o uguale a @var{y} +@item @var{x} @code{>} @var{y} @tab Vero se @var{x} @`e maggiore di @var{y} +@item @var{x} @code{>=} @var{y} @tab Vero se @var{x} @`e maggiore o uguale a @var{y} +@item @var{x} @code{==} @var{y} @tab Vero se @var{x} @`e uguale a @var{y} +@item @var{x} @code{!=} @var{y} @tab Vero se @var{x} @`e diverso da @var{y} +@item @var{x} @code{~} @var{y} @tab Vero se la stringa @var{x} corrisponde alla @dfn{regexp} rappresentata da @var{y} +@item @var{x} @code{!~} @var{y} @tab Vero se la stringa @var{x} non corrisponde alla @dfn{regexp} rappresentata da @var{y} +@item @var{indice} @code{in} @var{vettore} @tab Vero se il vettore @var{vettore} ha un elemento con indice @var{indice} +@end multitable +@end float + +Le espressioni di confronto valgono uno se sono vere e zero se false. +Quando si confrontano operandi di tipi diversi, gli operandi numerici sono +convertiti in stringhe usando il valore di @code{CONVFMT} +(@pxref{Conversione}). + +Il confronto tra stringhe avviene +confrontando il primo carattere di ciascuna stringa, poi il secondo carattere, +e cos@`{@dotless{i}} via. Quindi, @code{"10"} @`e minore di @code{"9"}. Se vi sono due +stringhe di cui una @`e il prefisso dell'altra, la stringa pi@`u corta @`e minore di +quella pi@`u lunga. Cos@`{@dotless{i}}, @code{"abc"} @`e minore di @code{"abcd"}. + +@cindex risoluzione di problemi, operatore @code{==} +@cindex problemi, risoluzione di, operatore @code{==} +@`E molto facile sbagliarsi scrivendo l'operatore @samp{==} e +omettendo uno dei due caratteri @samp{=}. Il risultato @`e sempre un codice +@command{awk} valido, ma il programma non fa quel che si voleva: + +@example +if (a = b) # oops! dovrebbe essere == b + @dots{} +else + @dots{} +@end example + +@noindent +A meno che @code{b} non sia zero o la stringa nulla, la parte @code{if} +del test ha sempre successo. Poich@'e gli operatori sono molto simili, +questo tipo di errore @`e molto difficile da individuare +rileggendo il codice sorgente. + +Il seguente elenco di espressioni illustra il tipo di confronti +che @command{awk} effettua e il risultato di ciascun confronto: + +@table @code +@item 1.5 <= 2.0 +Confronto numerico (vero) + +@item "abc" >= "xyz" +Confronto tra stringhe (falso) + +@item 1.5 != " +2" +Confronto tra stringhe (vero) + +@item "1e2" < "3" +Confronto tra stringhe (vero) + +@item a = 2; b = "2" +@itemx a == b +Confronto tra stringhe (vero) + +@item a = 2; b = " +2" +@itemx a == b +Confronto tra stringhe (falso) +@end table + +In quest'esempio: + +@example +$ @kbd{echo 1e2 3 | awk '@{ print ($1 < $2) ? "vero" : "falso" @}'} +@print{} falso +@end example + +@cindex espressioni di confronto, stringa vs.@: @dfn{regexp} +@c @cindex string comparison vs.@: regexp comparison +@c @cindex regexp comparison vs.@: string comparison +@noindent +il risultato @`e @samp{falso} perch@'e sia @code{$1} che @code{$2} +sono immessi dall'utente. Sono stringhe numeriche---quindi hanno entrambe +l'attributo @dfn{strnum}, che richiede un confronto di tipo numerico. +Lo scopo delle regole di confronto e dell'uso di stringhe numeriche @`e quello +di cercare di produrre il comportamento "meno inaspettato possibile", +pur "facendo la cosa giusta". + +I confronti di stringhe e i confronti di espressioni regolari sono molto +diversi. Per esempio: + +@example +x == "att" +@end example + +@noindent +ha il valore uno, ossia @`e vero, se la variabile @code{x} +@`e precisamente @samp{att}. Al contrario: + +@example +x ~ /att/ +@end example + +@noindent +ha il valore uno se @code{x} contiene @samp{att}, come +@code{"Oh, che matto che sono!"}. + +@cindex @code{~} (tilde), operatore @code{~} +@cindex tilde (@code{~}), operatore @code{~} +@cindex @code{!} (punto esclamativo), operatore @code{!~} +@cindex punto esclamativo (@code{!}), operatore @code{!~} +L'operando di destra degli operatori @samp{~} e @samp{!~} pu@`o essere sia una +costante @dfn{regexp} (@code{/}@dots{}@code{/}) che un'espressione ordinaria. +In quest'ultimo caso, il valore dell'espressione come stringa @`e usato come una +@dfn{regexp} dinamica (@pxref{Uso di @dfn{regexp}}; e +@pxref{Espressioni regolari calcolate}). + +@cindex @command{awk}, costanti @dfn{regexp} e +@cindex costanti @dfn{regexp} +@cindex @dfn{regexp}, costanti +Un'espressione regolare costante tra due barre @`e di per s@'e anche +un'espressione. @code{/@var{regexp}/} @`e un'abbreviazione per la seguente +espressione di confronto: + +@example +$0 ~ /@var{regexp}/ +@end example + +Una particolare posizione dove @code{/pippo/} @emph{non} @`e un'abbreviazione di +@samp{$0 ~ /pippo/} @`e quella in cui @`e l'operando di destra di @samp{~} o +@samp{!~}. +@xref{Usare le costanti @dfn{regexp}}, +dove questo punto @`e trattato in maggiore dettaglio. + +@node Confronto POSIX di stringhe +@subsubsection Confronto tra stringhe usando l'ordine di collazione locale + +Lo standard POSIX diceva che il confronto di stringhe viene effettuato secondo +l'@dfn{ordine di collazione} locale. Questo @`e l'ordine secondo il quale sono +disposti i caratteri, come definito dalla localizzazione (per una trattazione +pi@`u dettagliata, @pxref{Localizzazioni}). Quest'ordine normalmente @`e molto +diverso dal risultato ottenuto quando si esegue un confronto rigorosamente +"carattere per carattere".@footnote{Tecnicamente, il confronto di stringhe +dovrebbe funzionare come se le stringhe fossero confrontate usando la +funzione @code{strcoll()} di C.} + +Poich@'e questo comportamento differisce sensibilmente dalla pratica corrente, +@command{gawk} lo implementava solo quando eseguito in modalit@`a POSIX +(@pxref{Opzioni}). +Quest'esempio ilustra la differenza, in una localizzazione +@code{en_US.UTF-8}: + +@example +$ @kbd{gawk 'BEGIN @{ printf("ABC < abc = %s\n",} +> @kbd{("ABC" < "abc" ? "TRUE" : "FALSE")) @}'} +@print{} ABC < abc = TRUE +$ @kbd{gawk --posix 'BEGIN @{ printf("ABC < abc = %s\n",} +> @kbd{("ABC" < "abc" ? "TRUE" : "FALSE")) @}'} +@print{} ABC < abc = FALSE +@end example +Fortunatamente, dal mese di agosto 2016, un confronto basato sull'ordine +di collazione locale non @`e pi@`u richiesto per gli operatori @code{==} e +@code{!=}.@footnote{Si consulti il sito web +@uref{http://austingroupbugs.net/view.php?id=1070, +dell'Austin Group}.} Tuttavia, un confronto basato sull'ordine di +collazione locale @`e ancora richiesto per gli operatori @code{<}, +@code{<=}, @code{>} e @code{>=}. POSIX, quindi, raccomanda quanto +segue: + +@quotation +Poich@'e l'operatore @code{==} controlla che se le stringhe sono identiche, +e non se sono nell'ordine di collazione locale, le applicazioni che +devono controllare se le stringhe sono nell'ordine di collazione locale +possono usare: + +@example +a <= b && a >= b +@end example +@end quotation + +A partire dalla @value{PVERSION} 4.2, @command{gawk} continua a usare +l'ordine di collazione locale per @code{<}, @code{<=}, @code{>} +e @code{>=} solo se eseguito nella modalit@`a POSIX. + +@node Operatori booleani +@subsection Espressioni booleane +@cindex @dfn{and}, operatore logico-booleano +@cindex @dfn{or}, operatore logico-booleano +@cindex @dfn{not}, operatore logico-booleano +@cindex espressioni booleane +@cindex booleane, espressioni +@cindex operatori booleani, si veda espressioni booleane +@cindex booleani, operatori, si veda espressioni booleane +@cindex logici, operatori, si veda espressioni booleane +@cindex operatori logici, si veda espressioni booleane + +Un'@dfn{espressione booleana} @`e una combinazione di espressioni di confronto o +espressioni di ricerca, che usa gli operatori booleani "or" +(@samp{||}), "and" (@samp{&&}), e "not" (@samp{!}), facendo uso di +parentesi per controllare le nidificazioni. Il valore di verit@`a +dell'espressione booleana @`e calcolato calcolando i valori di verit@`a delle +espressioni componenti. Le espressioni booleane sono conosciute anche come +@dfn{espressioni logiche}. I due termini sono equivalenti. + +Le espressioni booleane possono essere usate in tutti i casi in cui @`e possibile +usare espressioni di confronto e di ricerca di corrispondenze. Si possono +usare nelle istruzioni @code{if}, @code{while}, @code{do} e @code{for} +(@pxref{Istruzioni}). +Hanno valori numerici (uno se vero, zero se falso) che entrano in gioco +se il risultato di un'espressione booleana @`e memorizzato in una variabile o +se @`e usato nei calcoli. + +Inoltre, ogni espressione booleana @`e anche un modello di ricerca valido, cos@`{@dotless{i}} +se ne pu@`o usare uno come modello di ricerca per controllare l'esecuzione di +regole. Gli operatori booleani sono: + +@table @code +@item @var{booleano1} && @var{booleano2} +Vero se @var{booleano1} e @var{booleano2} sono entrambi veri. Per esempio, +la seguente istruzione stampa il record in input corrente se contiene +sia @samp{edu} che @samp{li}: + +@example +if ($0 ~ /edu/ && $0 ~ /li/) print +@end example + +@cindex effetti collaterali, operatori booleani +La sottoespressione @var{booleano2} viene valutata solo se @var{booleano1} +@`e vero. Questo pu@`o comportare una differenza laddove @var{booleano2} contenga +espressioni che hanno effetti collaterali. Nel caso di @samp{$0 ~ /pippo/ && +($2 == pluto++)}, la variabile @code{pluto} non viene incrementata se non c'@`e +nessuna sottostringa @samp{pippo} nel record. + +@item @var{booleano1} || @var{booleano2} +Vero se almeno uno tra @var{booleano1} e @var{booleano2} @`e vero. +Per esempio, la seguente istruzione stampa tutti i record dell'input che +contengono @samp{edu} @emph{oppure} +@samp{li}: + +@example +if ($0 ~ /edu/ || $0 ~ /li/) print +@end example + +La sottoespressione @var{booleano2} viene valutata solo se @var{booleano1} +@`e falso. Questo pu@`o comportare una differenza quando @var{booleano2} contiene +espressioni che hanno effetti collaterali. +(Perci@`o, questo confronto non individua mai i record che contengono sia +@samp{edu} che @samp{li}: non appena @samp{edu} viene trovato, +l'intero confronto @`e concluso positivamente.) + +@item ! @var{booleano} +Vero se @var{booleano} @`e falso. Per esempio, +il seguente programma stampa @samp{nessuna home!} nel +caso insolito che la variabile d'ambiente @env{HOME} +non sia stata definita: + +@example +BEGIN @{ if (! ("HOME" in ENVIRON)) + print "nessuna home!" @} +@end example + +(L'operatore @code{in} @`e descritto in +@ref{Visitare elementi}.) +@end table + +@cindex cortocircuito, operatori +@cindex operatori di cortocircuito +@cindex @code{&} (e commerciale), operatore @code{&&} +@cindex e commerciale (@code{&}), operatore @code{&&} +@cindex @code{|} (barra verticale), operatore @code{||} +@cindex barra verticale (@code{|}), operatore @code{||} +Gli operatori @samp{&&} e @samp{||} sono chiamati operatori di +@dfn{cortocircuito} per il modo in cui funzionano. La valutazione dell'intera +espressione @`e "cortocircuitata" se il risultato pu@`o gi@`a essere determinato +prima di aver completato interamente la valutazione. + +@cindex continuazione di riga +Le istruzioni che finiscono con @samp{&&} o @samp{||} si possono continuare +semplicemente mettendo un ritorno a capo dopo di esse. Per@`o non si pu@`o mettere +un ritorno a capo @emph{prima} di questi operatori senza usare la +continuazione tramite la barra inversa (@pxref{Istruzioni/Righe}). + +@cindex @code{!} (punto esclamativo), operatore @code{!} +@cindex punto esclamativo (@code{!}), operatore @code{!} +@cindex ritorno a capo +@cindex variabili di tipo indicatore [@dfn{flag}] +@cindex @dfn{flag} [indicatore], variabili +Il valore reale di un'espressione che usa l'operatore @samp{!} @`e uno +o zero, a seconda del valore di verit@`a dell'espressione a cui +@`e applicato. +L'operatore @samp{!} spesso @`e utile per cambiare il senso di una variabile +indicatore [@dfn{flag}] da falso a vero e viceversa. Per esempio, il seguente +programma @`e un modo per stampare righe poste tra due speciali righe +delimitatrici: + +@example +$1 == "START" @{ pertinente = ! pertinente; next @} +pertinente @{ print @} +$1 == "END" @{ pertinente = ! pertinente; next @} +@end example + +@noindent +La variabile @code{pertinente}, cos@`{@dotless{i}} come tutte le variabili di @command{awk}, +@`e inizializzata a zero, che vale anche "falso". Quando viene trovata +una riga il cui primo campo @`e @samp{START}, il valore di @code{pertinente} +viene commutato a vero, usando @samp{!}. La regola nella riga seguente stampa righe finch@'e +@code{pertinente} resta vero. Quando viene trovata una riga il cui primo +campo @`e @samp{END}, @code{pertinente} viene nuovamente commutata a +falso.@footnote{Questo programma ha un bug; stampa righe che iniziano con +@samp{END}. Come si pu@`o risolvere?} + +@ignore +Scott Deifik points out that this program isn't robust against +bogus input data, but the point is to illustrate the use of `!', +so we'll leave well enough alone. +@end ignore + +Pi@`u comunemente, l'operatore @samp{!} viene usato nelle condizioni delle +istruzioni @code{if} e @code{while}, dove ha pi@`u senso formulare espressioni +logiche in negativo: + +@example +if (! @var{qualche condizione} || @var{qualche altra condizione}) @{ + @var{@dots{} fai un'operazione a piacere @dots{}} +@} +@end example + +@cindex @code{next}, istruzione +@quotation NOTA +L'istruzione @code{next} viene trattata in +@ref{Istruzione next}. +@code{next} dice ad @command{awk} di tralasciare il resto delle regole, +leggere il record successivo, e iniziare a elaborare le regole partendo +nuovamente dalla prima. +Il motivo @`e quello di evitare di stampare le righe delimitatrici +@samp{START} e @samp{END}. +@end quotation + +@node Espressioni condizionali +@subsection Espressioni condizionali +@cindex condizionali, espressioni +@cindex espressioni condizionali +@cindex espressioni, selezionare + +Un'@dfn{espressione condizionale} @`e un tipo particolare di espressione che ha +tre operandi. Consente di usare il primo valore dell'espressione per +scegliere una o l'altra delle due ulteriori espressioni. +L'espressione condizionale in @command{awk} @`e la stessa di quella del +linguaggio C, ovvero: + +@example +@var{selettore} ? @var{espr-se-vero} : @var{espr-se-falso} +@end example + +@noindent +Ci sono tre sottoespressioni. La prima, @var{selettore}, viene sempre +calcolata per prima. Se @`e "vera" (non zero o non nulla), viene poi calcolata +@var{espr-se-vero} e il suo valore diventa il valore dell'intera espressione. +Altrimenti, la seconda espressione che viene calcolata @`e @var{espr-se-falso} +e il suo valore diventa il valore dell'intera espressione. +Per esempio, la seguente espressione produce il valore assoluto di @code{x}: + +@example +x >= 0 ? x : -x +@end example + +@cindex effetti collaterali, espressioni condizionali +Ogni volta che viene calcolata un'espressione condizionale, solo una delle +espressioni @var{espr-se-vero} e @var{espr-se-falso} viene usata; l'altra +@`e ignorata. Questo @`e importante quando le espressioni hanno effetti +collaterali. Per esempio, quest'espressione condizionale esamina l'elemento +@code{i} del vettore @code{a} o del vettore @code{b}, e incrementa @code{i}: + +@example +x == y ? a[i++] : b[i++] +@end example + +@noindent +Questa istruzione garantisce che @code{i} sia incrementato una volta sola +per ogni esecuzione dell'istruzione stessa, perch@'e ogni volta viene eseguita +solo una delle due espressioni di incremento, mentre l'altra viene +ignorata. +@iftex +@xrefil{Vettori}, +@end iftex +@ifnottex +@xref{Vettori}, +@end ifnottex +per maggiori informazioni sui vettori. + +@cindex differenze tra @command{awk} e @command{gawk}, continuazione di riga +@cindex continuazione di riga, @command{gawk} +@cindex @command{gawk}, continuazione di riga in +Come estensione minore di @command{gawk}, +un'istruzione che usa @samp{?:} si pu@`o continuare mettendo +semplicemente un ritorno a capo dopo i due caratteri. +Tuttavia, se si mette un ritorno a capo @emph{prima} dei due +caratteri, la continuazione non funziona, se non si aggiunge anche la barra inversa +(@pxref{Istruzioni/Righe}). +Se viene specificata l'opzione @option{--posix} +(@pxref{Opzioni}), quest'estensione @`e disabilitata. + +@node Chiamate di funzione +@section Chiamate di funzione +@cindex chiamata di funzione + +Una @dfn{funzione} @`e un nome per richiedere un particolare calcolo. +Il nome permette di richiamare +la funzione da qualsiasi punto del programma. +Per esempio, la funzione @code{sqrt()} calcola la radice quadrata di un numero. + +@cindex funzioni predefinite +Un certo numero di funzioni sono @dfn{predefinite}, ossia sono +disponibili in ogni programma @command{awk}. La funzione @code{sqrt()} @`e una +di queste. @xref{Funzioni predefinite} per un elenco di funzioni +predefinite e per le loro rispettive descrizioni. In aggiunta, l'utente pu@`o +definire delle funzioni da usare nel proprio programma. +@xref{Funzioni definite dall'utente} +per istruzioni su come farlo. +Infine, @command{gawk} permette di scrivere funzioni in C o in C++ che possono +essere chiamate dal proprio programma (@pxref{Estensioni dinamiche}). + +@cindex argomenti, nelle chiamate di funzione +Una funzione viene utilizzata invocandola tramite un'espressione di +@dfn{chiamata di funzione}, che consiste nel nome della funzione seguito +immediatamente da una lista di @dfn{argomenti} tra parentesi. Gli argomenti +sono espressioni che forniscono i materiali grezzi su cui opera la funzione. +Quando ci sono pi@`u argomenti, questi sono separati da virgole. Se +non ci sono argomenti, basta scrivere @samp{()} dopo il nome della funzione. +Gli esempi che seguono mostrano chiamate di funzione con e senza argomenti: + +@example +sqrt(x^2 + y^2) @ii{un argomento} +atan2(y, x) @ii{due argomenti} +rand() @ii{nessun argomento} +@end example + +@cindex risoluzione di problemi, sintassi della chiamata di funzione +@cindex problemi, risoluzione di, sintassi della chiamata di funzione +@quotation ATTENZIONE +Non ci dev'essere nessuno spazio tra il nome della funzione e la parentesi +aperta! Un nome di funzione definita dall'utente pu@`o essere scambiata per +il nome di una +variabile: uno spazio renderebbe l'espressione simile alla concatenazione di +una variabile con un'espressione racchiusa tra parentesi. +Per le funzioni predefinite, lo spazio prima delle parentesi non crea problemi, +ma @`e meglio non prendere l'abitudine di usare spazi per evitare errori con le +funzioni definite dall'utente. +@end quotation + +Ogni funzione richiede uno specifico numero di argomenti. +Per esempio, la funzione @code{sqrt()} dev'essere chiamata con +un solo argomento, il numero del quale si vuole estrarre la radice quadrata: + +@example +sqrt(@var{argomento}) +@end example + +Alcune delle funzioni predefinite hanno uno o pi@`u argomenti opzionali. +Se questi argomenti non vengono forniti, le funzioni +usano un valore di default appropriato. +@xref{Funzioni predefinite} per tutti i dettagli. Se sono omessi argomenti +in chiamate a funzioni definite dall'utente, tali argomenti sono considerati +essere variabili locali. Il valore di tali variabili locali +@`e la stringa nulla se usate in un contesto che richiede una stringa +di caratteri, e lo zero se @`e richiesto +un valore numerico +(@pxref{Funzioni definite dall'utente}). + +Come funzionalit@`a avanzata, @command{gawk} prevede la possibilit@`a di +effettuare chiamate di funzione +indirette, il che permette di scegliere la funzione da chiamare al momento +dell'esecuzione, invece che nel momento in cui si scrive il codice sorgente +del programma. +Si rimanda la trattazione di questa funzionalit@`a +a un secondo momento; si veda @ref{Chiamate indirette}. + +@cindex effetti collaterali, chiamate di funzione +Come ogni altra espressione, la chiamata di funzione ha un valore, chiamato +spesso @dfn{valore di ritorno}, che @`e calcolato dalla funzione +in base agli argomenti dati. In quest'esempio, il valore di ritorno +di @samp{sqrt(@var{argomento})} @`e la radice quadrata di @var{argomento}. +Il seguente programma legge numeri, un numero per riga, e stampa +la radice quadrata di ciascuno: + +@example +$ @kbd{awk '@{ print "La radice quadrata di", $1, "@`e", sqrt($1) @}'} +@kbd{1} +@print{} La radice quadrata di 1 @`e 1 +@kbd{3} +@print{} La radice quadrata di 3 @`e 1.73205 +@kbd{5} +@print{} La radice quadrata di 5 @`e 2.23607 +@kbd{Ctrl-d} +@end example + +Una funzione pu@`o avere anche effetti collaterali, come assegnare +valori a certe variabili o effettuare operazioni di I/O. +Questo programma mostra come la funzione @code{match()} +(@pxref{Funzioni per stringhe}) +cambia le variabili @code{RSTART} e @code{RLENGTH}: + +@example +@{ + if (match($1, $2)) + print RSTART, RLENGTH + else + print "non uguali" +@} +@end example + +@noindent +Qui vediamo un'esecuzione di esempio: + +@example +$ @kbd{awk -f matchit.awk} +@kbd{aaccdd c+} +@print{} 3 2 +@kbd{pippo pluto} +@print{} non uguali +@kbd{abcdefg e} +@print{} 5 1 +@end example + +@node Precedenza +@section Precedenza degli operatori (Come si nidificano gli operatori) +@cindex precedenza +@cindex operatori, precedenza + +La @dfn{precedenza degli operatori} determina come gli operatori vengono +raggruppati quando diversi operatori appaiono uno vicino all'altro in +un'espressione. +Per esempio, @samp{*} ha una precedenza pi@`u alta di @samp{+}; cos@`{@dotless{i}}, +@samp{a + b * c} moltiplica @code{b} e @code{c}, e poi aggiunge @code{a} al +prodotto (ovvero esegue @samp{a + (b * c)}). + +La normale precedenza degli operatori pu@`o essere cambiata usando delle +parentesi. Si possono vedere le regole di precedenza come un modo per +indicare dove si sarebbero dovute mettere delle parentesi. Di fatto, +@`e cosa saggia usare sempre le parentesi +in presenza di una combinazione di operatori insolita, perch@'e altre persone +che leggono il programma potrebbero non ricordare quale sia la precedenza +in quel particolare caso. +Anche dei programmatori esperti a volte dimenticano le regole esatte, +il che porta a commettere errori. +Usare esplicitamente le parentesi previene qualunque errore +di questo tipo. + +Quando vengono usati insieme operatori con uguale precedenza, quello pi@`u a +sinistra viene raggruppato per primo, ad eccezione degli operatori di +assegnamento, condizionali e di elevamento a potenza, che vengono raggruppati +nell'ordine opposto. +Quindi, @samp{a - b + c} raggruppa come @samp{(a - b) + c} e +@samp{a = b = c} raggruppa come @samp{a = (b = c)}. + +Normalmente la precedenza degli operatori unari di prefisso non ha importanza, +perch@'e c'@`e un solo modo di interpretarli: prima il pi@`u interno. Quindi, +@samp{$++i} significa @samp{$(++i)} e +@samp{++$x} significa @samp{++($x)}. Tuttavia, quando un altro operatore segue +l'operando, la precedenza degli operatori unari pu@`o avere importanza. +@samp{$x^2} significa @samp{($x)^2}, ma @samp{-x^2} significa +@samp{-(x^2)}, perch@'e @samp{-} ha precedenza pi@`u bassa rispetto a @samp{^}, +mentre @samp{$} ha precedenza pi@`u alta. +Inoltre, gli operatori non possono essere combinati in modo tale da violare le +regole di precedenza; per esempio, @samp{$$0++--} non @`e un'espressione valida +perch@'e il primo @samp{$} ha precedenza pi@`u alta di +@samp{++}; per evitare il problema l'espressione pu@`o essere scritta come +@samp{$($0++)--}. + +Questa lista illustra gli operatori di @command{awk}, in ordine di precedenza +dalla pi@`u alta alla pi@`u bassa: + +@c @asis for docbook to come out right +@table @asis +@item @code{(}@dots{}@code{)} +Raggruppamento. + +@cindex @code{$} (dollaro), operatore di campo @code{$} +@cindex dollaro (@code{$}), operatore di campo @code{$} +@item @code{$} +Riferimento a un campo. + +@cindex @code{+} (pi@`u), operatore @code{++} +@cindex pi@`u (@code{+}), operatore @code{++} +@cindex @code{-} (meno), operatore @code{--} +@cindex meno (@code{-}), operatore @code{--} +@item @code{++ --} +Incremento, decremento. + +@cindex @code{^} (circonflesso), operatore @code{^} +@cindex circonflesso (@code{^}), operatore @code{^} +@cindex @code{*} (asterisco), operatore @code{**} +@cindex asterisco (@code{*}), operatore @code{**} +@item @code{^ **} +Elevamento a potenza. Questi operatori sono raggruppati da destra verso +sinistra. + +@cindex @code{+} (pi@`u), operatore @code{+} +@cindex pi@`u (@code{+}), operatore @code{+} +@cindex @code{-} (meno), operatore @code{-} +@cindex meno (@code{-}), operatore @code{-} +@cindex @code{!} (punto esclamativo), operatore @code{!} +@cindex punto esclamativo (@code{!}), operatore @code{!} +@item @code{+ - !} +Pi@`u, meno, ``not'' logico, unari. + +@cindex @code{*} (asterisco), operatore @code{*}, come operatore di moltiplicazione +@cindex asterisco (@code{*}), operatore @code{*}, come operatore di moltiplicazione +@cindex @code{/} (barra), operatore @code{/} +@cindex barra (@code{/}), operatore @code{/} +@cindex @code{%} (percento), operatore @code{%} +@cindex percento (@code{%}), operatore @code{%} +@item @code{* / %} +Moltiplicazione, divisione, resto di una divisione. + +@cindex @code{+} (pi@`u), operatore @code{+} +@cindex pi@`u (@code{+}), operatore @code{+} +@cindex @code{-} (meno), operatore @code{-} +@cindex meno (@code{-}), operatore @code{-} +@item @code{+ -} +Addizione, sottrazione. + +@item Concatenazione di stringhe +Non c'@`e un simbolo speciale per la concatenazione. +Gli operandi sono semplicemente scritti uno accanto all'altro. +(@pxref{Concatenazione}). + +@cindex @code{<} (parentesi acuta sinistra), operatore @code{<} +@cindex parentesi acuta sinistra (@code{<}), operatore @code{<} +@cindex @code{<} (parentesi acuta sinistra), operatore @code{<=} +@cindex parentesi acuta sinistra (@code{<}), operatore @code{<=} +@cindex @code{>} (parentesi acuta destra), operatore @code{>=} +@cindex parentesi acuta destra (@code{>}), operatore @code{>=} +@cindex @code{>} (parentesi acuta destra), operatore @code{>} +@cindex parentesi acuta destra (@code{>}), operatore @code{>} +@cindex @code{=} (uguale), operatore @code{==} +@cindex uguale (@code{=}), operatore @code{==} +@cindex @code{!} (punto esclamativo), operatore @code{!=} +@cindex punto esclamativo (@code{!}), operatore @code{!=} +@cindex @code{>} (parentesi acuta destra), operatore @code{>>} (I/O) +@cindex parentesi acuta destra (@code{>}), operatore @code{>>} (I/O) +@cindex operatori, input/output +@cindex @code{|} (barra verticale), operatore @code{|} (I/O) +@cindex barra verticale (@code{|}), operatore @code{|} (I/O) +@cindex operatori, input/output +@cindex @code{|} (barra verticale), operatore @code{|&} (I/O) +@cindex barra verticale (@code{|}), operatore @code{|&} (I/O) +@cindex operatori, input/output +@item @code{< <= == != > >= >> | |&} +Operatori relazionali e ridirezione. +Gli operatori relazionali e le ridirezioni hanno lo stesso livello di +precedenza. I caratteri come @samp{>} servono sia come operatori relazionali +che come ridirezioni; la distinzione tra i due significati dipende dal +contesto. + +@cindex istruzione @code{print}, operatori I/O nell' +@cindex istruzione @code{printf}, operatori I/O nell' +Si noti che gli operatori di ridirezione I/O nelle istruzioni @code{print} e +@code{printf} appartengono al livello dell'istruzione, non alle espressioni. +La ridirezione non produce un'espressione che potrebbe essere l'operando di un +altro operatore. Di conseguenza, non ha senso usare un operatore di +ridirezione vicino a un altro operatore con precedenza pi@`u bassa senza +parentesi. Tali combinazioni generano errori di sintassi +(p.es., @samp{print pippo > a ? b : c}). +Il modo corretto di scrivere quest'istruzione @`e @samp{print pippo > (a ? b : c)}. + +@cindex @code{~} (tilde), operatore @code{~} +@cindex tilde (@code{~}), operatore @code{~} +@cindex @code{!} (punto esclamativo), operatore @code{!~} +@cindex punto esclamativo (@code{!}), operatore @code{!~} +@item @code{~ !~} +Corrispondenza, non corrispondenza. + +@cindex @code{in}, operatore +@item @code{in} +Appartenenza a un vettore. + +@cindex @code{&} (e commerciale), operatore @code{&&} +@cindex e commerciale (@code{&}), operatore @code{&&} +@item @code{&&} +``and'' logico. + +@cindex @code{|} (barra verticale), operatore @code{||} +@cindex barra verticale (@code{|}), operatore @code{||} +@item @code{||} +``or'' logico. + +@cindex @code{?} (punto interrogativo), operatore @code{?:} +@cindex punto interrogativo (@code{?}), operatore @code{?:} +@item @code{?:} +Operatore condizionale. Questo operatore raggruppa da destra verso sinistra. + +@cindex @code{+} (pi@`u), operatore @code{+=} +@cindex pi@`u (@code{+}), operatore @code{+=} +@cindex @code{-} (meno), operatore @code{-=} +@cindex meno (@code{-}), operatore @code{-=} +@cindex @code{*} (asterisco), operatore @code{*=} +@cindex asterisco (@code{*}), operatore @code{*=} +@cindex @code{*} (asterisco), operatore @code{**=} +@cindex asterisco (@code{*}), operatore @code{**=} +@cindex @code{/} (barra), operatore @code{/=} +@cindex barra (@code{/}), operatore @code{/=} +@cindex @code{%} (percento), operatore @code{%=} +@cindex percento (@code{%}), operatore @code{%=} +@cindex @code{^} (circonflesso), operatore @code{^=} +@cindex circonflesso (@code{^}), operatore @code{^=} +@item @code{= += -= *= /= %= ^= **=} +Assegnamento. Questi operatori raggruppano da destra verso sinistra. +@end table + +@cindex POSIX @command{awk}, @code{**} e +@cindex portabilit@`a, operatori, non in POSIX @command{awk} +@quotation NOTA +Gli operatori @samp{|&}, @samp{**} e @samp{**=} non sono definiti da POSIX. +Per la massima portabilit@`a, @`e meglio non usarli. +@end quotation + +@node Localizzazioni +@section Il luogo fa la differenza +@cindex localizzazione, definizione di + +I moderni sistemi prevedono la nozione di @dfn{localizzazione}: un modo per +informare il sistema sulla serie di caratteri e sulla lingua locali. +Lo standard ISO C definisce una localizzazione di default @code{"C"}, che @`e +l'ambiente tipico a cui molti programmatori in C sono abituati. + +Un tempo, le impostazioni della localizzazione avevano influenza sulla +ricerca di corrispondenze tramite @dfn{regexp}, ma ora non @`e pi@`u cos@`{@dotless{i}} +(@pxref{Intervalli e localizzazione}). + +La localizzazione pu@`o influire sulla separazione dei record. Per il caso +normale di @samp{RS = "\n"}, la localizzazione @`e generalmente irrilevante. +Per altri separatori di record di un solo carattere, impostare +la variabile d'ambiente @samp{LC_ALL=C} +garantisce una migliore efficienza nella lettura dei record. Altrimenti, +@command{gawk} dovrebbe fare diverse chiamate di funzione, @emph{per ogni +carattere in input}, per determinare la fine del record. + +La localizzazione pu@`o influire sulla formattazione delle date e delle ore +(@pxref{Funzioni di tempo}). Per esempio, un modo comune per abbreviare la +data 4 settembre 2015, negli Stati Uniti @`e ``9/4/15.'' In molti paesi +dell'Europa, invece, l'abbreviazione @`e "4.9.15". Quindi, la specifica di +formato +@code{%x} in una localizzazione @code{"US"} potrebbe produrre @samp{9/4/15}, +mentre in una localizzazione @code{"EUROPA"}, potrebbe produrre @samp{4.9.15}. + +Secondo POSIX, anche il confronto tra stringhe @`e influenzato dalla +localizzazione (come nelle espressioni regolari). I dettagli sono descritti in +@ref{Confronto POSIX di stringhe}. + +Infine, la localizzazione influenza il valore del separatore decimale +usato quando @command{gawk} analizza i dati in input. Questo @`e stato +trattato nel dettaglio in @ref{Conversione}. + +@node Sommario delle espressioni +@section Sommario + +@itemize @value{BULLET} +@item +Le espressioni sono gli elementi base dei calcoli eseguiti nei programmi. +Sono costruite a partire da costanti, variabili, chiamate di funzione e dalla +combinazione di vari tipi di valori tramite operatori. + +@item +@command{awk} fornisce tre tipi di costanti: numerica, di stringa e +di @dfn{regexp}. Le costanti numeriche in @command{gawk} si possono +specificare nei sistemi ottale ed esadecimale (con base 8 e 16), e anche nel +sistema decimale (base 10). In alcuni contesti, una costante @dfn{regexp} +isolata come @code{/pippo/} ha lo stesso significato di @samp{$0 ~ /pippo/}. + +@item +Le variabili contengono valori che possono essere usati diverse volte nei +calcoli. Un certo numero di variabili predefinite forniscono informazioni al +programma @command{awk}, mentre altre permettono il controllo del comportamento +di @command{awk}. + +@item +I numeri sono automaticamente convertiti in stringhe, e le stringhe in numeri, +a seconda delle necessit@`a di @command{awk}. I valori numerici sono convertiti +come se fossero formattati con @code{sprintf()} usando il formato contenuto in +@code{CONVFMT}. La localizzazione pu@`o influire sulle conversioni. + +@item +In @command{awk} ci sono gli operatori aritmetici di uso comune (addizione, +sottrazione, moltiplicazione, divisione, modulo), e il pi@`u e il meno unari. +Ci sono anche operatori di confronto, operatori booleani, una verifica +dell'esistenza di una chiave in +un vettore, e operatori per la ricerca di corrispondenze con espressioni +regolari. La concatenazione di stringhe @`e effettuata mettendo due espressioni +una vicino all'altra; non c'@`e nessun operatore esplicito. +L'operatore con tre operandi @samp{?:} fornisce una verifica ``if-else'' +all'interno delle espressioni. + +@item +Gli operatori di assegnamento forniscono delle comode forme brevi per le comuni +operazioni aritmetiche. + +@item +In @command{awk}, un valore @`e considerato vero se @`e diverso da zero +@emph{oppure} non nullo. Altrimenti, il valore @`e falso. + +@item +Il tipo di una variabile viene impostata a ogni assegnamento e pu@`o cambiare +durante il suo ciclo di vita. Il tipo determina il comportamento della +variabile nei confronti (di tipo stringa o numerici). + +@item +Le chiamate di funzione restituiscono un valore che pu@`o essere usato come parte +di un'espressione pi@`u lunga. Le espressioni usate per passare valori di +parametro vengono valutate completamente prima di chiamare la funzione. +@command{awk} fornisce funzioni predefinite e prevede quelle definite +dall'utente; questo @`e descritto in +@ref{Funzioni}. + +@item +La precedenza degli operatori specifica l'ordine secondo il quale vengono +effettuate le operazioni, a meno che quest'ordine non sia esplicitamente +alterato +tramite parentesi. Le regole di precedenza degli operatori di @command{awk} +sono compatibili con quelle del linguaggio C. + +@item +La localizzazione pu@`o influire sul formato dei dati in uscita da un programma +@command{awk}, e occasionalmente sul formato dei dati letti in input. + +@end itemize + +@node Criteri di ricerca e azioni +@chapter Criteri di ricerca, azioni e variabili +@cindex criteri di ricerca +@cindex @dfn{pattern}, si veda criteri di ricerca +@cindex espressione di ricerca + +Come gi@`a visto, ogni istruzione @command{awk} consiste di un criterio di +ricerca [@dfn{pattern}] a cui @`e associata un'azione. Questo @value{CHAPTER} +descrive come specificare criteri e azioni, cosa @`e possibile +fare tramite le azioni e quali sono le variabili predefinite in +@command{awk}. + +Le regole @dfn{criterio di ricerca--azione} e le istruzioni che si possono +dare all'interno delle azioni formano il nucleo centrale dei programmi +scritti in @command{awk}. +In un certo senso, tutto quanto si @`e visto finora costituisce le fondamenta +sulle quali sono costruiti i programmi. @`E giunto il momento di iniziare a +costruire qualcosa di utile. + +@menu +* Panoramica sui criteri di ricerca:: Come scrivere un criterio di ricerca. +* Usare variabili di shell:: come usare variabili della shell in + @command{awk}. +* Panoramica sulle azioni:: Come scrivere un'azione. +* Istruzioni:: Descrizione dettagliata delle varie + istruzioni di controllo. +* Variabili predefinite:: Sommario delle variabili predefinite. +* Sommario criteri e azioni:: Sommario di criteri di ricerca e azioni. +@end menu + +@node Panoramica sui criteri di ricerca +@section Elementi di un criterio di ricerca + +@menu +* @dfn{regexp} come criteri di ricerca:: Usare espressioni regolari come + criteri di ricerca. +* Espressioni come criteri di ricerca:: Qualsiasi espressione pu@`o servire da + criterio di ricerca. +* Intervalli:: Coppie di espressioni regolari per + delimitare una ricerca. +* BEGIN/END:: Specificare regole di inizio e fine programma. +* BEGINFILE/ENDFILE:: Due condizioni speciali per controlli avanzati. +* Vuoto:: Il criterio di ricerca vuoto, che + corrisponde a ogni record. +@end menu + +@cindex criteri di ricerca, tipi di +I criteri di ricerca in @command{awk} controllano l'esecuzione di +azioni: un'azione viene eseguita +quando il criterio di ricerca associato ad essa @`e soddisfatto dal +record in input corrente. +La tabella seguente @`e un sommario dei tipi di criteri di ricerca in +@command{awk}: + +@table @code +@item /@var{espressione regolare}/ +Un'espressione regolare. @`E verificata quando il testo di un +record in input corrisponde all'espressione regolare. +@iftex +(@xrefIl{Espressioni regolari}.) +@end iftex +@ifnottex +(@xref{Espressioni regolari}.) +@end ifnottex + +@item @var{espressione} +Una singola espressione. @`E verificata quando il suo valore @`e +diverso da zero (se di tipo numerico) o non nullo (se @`e una stringa). +(@xref{Espressioni come criteri di ricerca}.) + +@item @var{inizio_interv}, @var{fine_interv} +Una coppia di criteri di ricerca separati da una virgola, che specificano un +@dfn{intervallo} di record. +L'intervallo comprende sia il record iniziale che corrisponde a @var{inizio_interv} +sia il record finale che corrisponde a @var{fine_interv}. +(@xref{Intervalli}.) + +@item BEGIN +@itemx END +Criteri di ricerca speciali che consentono azioni di inizializzazione o +di pulizia in un programma @command{awk}. +(@xref{BEGIN/END}.) + +@item BEGINFILE +@itemx ENDFILE +Criteri di ricerca speciali che consentono azioni di inizializzazione o di +pulizia da eseguire all'inizio o alla fine di ogni file in input. +(@xref{BEGINFILE/ENDFILE}.) + +@item @var{vuoto} +Il criterio di ricerca vuoto corrisponde a ciascun record in input. +(@xref{Vuoto}.) +@end table + +@node @dfn{regexp} come criteri di ricerca +@subsection Espressioni regolari come criteri di ricerca +@cindex criteri di ricerca, espressioni come +@cindex espressioni regolari, come criteri di ricerca + +Le espressioni regolari sono uno dei primi tipi di criteri di ricerca +presentati in questo @value{DOCUMENT}. +Questo tipo di criterio di ricerca @`e semplicemente una costante @dfn{regexp} +posta nella parte @dfn{criterio di ricerca} di una regola. Equivale a +scrivere @samp{$0 ~ /@var{criterio di ricerca}/}. +Il criterio di ricerca @`e verificato quando il record in input corrisponde +alla @dfn{regexp}. +Per esempio: + +@example +/pippo|pluto|paperino/ @{ personaggi_Disney++ @} +END @{ print personaggi_Disney, "Personaggi Disney visti" @} +@end example + +@node Espressioni come criteri di ricerca +@subsection Espressioni come criteri di ricerca +@cindex espressioni regolari, come criteri di ricerca + +Qualsiasi espressione @command{awk} pu@`o essere usata come un criterio di +ricerca @command{awk}. +Il criterio di ricerca @`e verificato se il valore dell'espressione @`e diverso +da zero (se @`e un numero), o non nullo (se @`e una stringa). +L'espressione @`e ricalcolata ogni volta che la regola viene applicata a un +nuovo record in input. Se l'espressione usa campi come @code{$1}, il suo +valore dipende direttamente dal contenuto del record in input appena letto; +altrimenti, dipende solo da quel che @`e accaduto fino a quel momento durante +l'esecuzione del programma @command{awk}. + +@cindex espressioni di confronto, come criteri di ricerca +@cindex criteri di ricerca, espressioni di confronto come +Le espressioni di confronto, che usano gli operatori di confronto descritti in +@ref{Tipi di variabile e confronti}, +sono un tipo di criterio di ricerca usato frequentemente. +Anche le @dfn{regexp}, verificate o non verificate, sono tipi di espressioni molto frequenti. +L'operando a sinistra degli operatori @samp{~} e @samp{!~} @`e una stringa. +L'operando di destra @`e un'espressione regolare costante delimitata da +barre (@code{/@var{@dfn{regexp}}/}) o qualsiasi espressione il cui valore come +stringa @`e usato come un'espressione regolare dinamica +(@pxref{Espressioni regolari calcolate}). +L'esempio seguente stampa il secondo campo di ogni record in input +il cui primo campo sia esattamente @samp{li}: + +@cindex @code{/} (barra), criteri di ricerca e +@cindex barra (@code{/}), criteri di ricerca e +@cindex @code{~} (tilde), operatore @code{~} +@cindex tilde (@code{~}), operatore @code{~} +@cindex @code{!} (punto esclamativo), operatore @code{!~} +@cindex punto esclamativo (@code{!}), operatore @code{!~} +@example +$ @kbd{awk '$1 == "li" @{ print $2 @}' mail-list} +@end example + +@noindent +(Il programma non stampa alcun output, perch@'e nessuna persona ha come nome esattamente @samp{li}.) +Si veda la differenza con il seguente confronto di espressione regolare, che +individua invece qualsiasi record il cui primo campo @emph{contenga} @samp{li}: + +@example +$ @kbd{awk '$1 ~ /li/ @{ print $2 @}' mail-list} +@print{} 555-5553 +@print{} 555-6699 +@end example + +@cindex @dfn{regexp}, costanti, come criteri di ricerca +@cindex criteri di ricerca, costanti @dfn{regexp} come +Una costante @dfn{regexp} usata come criterio di ricerca @`e anche un +caso speciale di criterio di ricerca costituito da un'espressione. +All'espressione @code{/li/} viene assegnato il valore uno se @samp{li} +viene trovato nel record in input corrente. Quindi, come criterio di ricerca, +@code{/li/} individua tutti i record che contengono la stringa @samp{li}. + +@cindex espressioni booleane, come criteri di ricerca +Anche le espressioni booleane sono frequentemente usate come criteri di +ricerca. Se un criterio di ricerca +individua o no un record in input dipende dalla verifica delle +sottoespressioni da cui @`e composto. +Per esempio, il seguente comando stampa tutti i record in +@file{mail-list} che contengono sia @samp{edu} che @samp{li}: + +@example +$ @kbd{awk '/edu/ && /li/' mail-list} +@print{} Samuel 555-3430 samuel.lanceolis@@shu.edu A +@end example + +Il seguente comando stampa tutti i record in +@file{mail-list} che contengono @samp{edu} @emph{oppure} @samp{li} +(o entrambi, naturalmente): + +@example +$ @kbd{awk '/edu/ || /li/' mail-list} +@print{} Amelia 555-5553 amelia.zodiacusque@@gmail.com F +@print{} Broderick 555-0542 broderick.aliquotiens@@yahoo.com R +@print{} Fabius 555-1234 fabius.undevicesimus@@ucb.edu F +@print{} Julie 555-6699 julie.perscrutabor@@skeeve.com F +@print{} Samuel 555-3430 samuel.lanceolis@@shu.edu A +@print{} Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R +@end example + +Il seguente comando stampa tutti i record in +@file{mail-list} che @emph{non} contengono la stringa @samp{li}: + +@example +$ @kbd{awk '! /li/' mail-list} +@print{} Anthony 555-3412 anthony.asserturo@@hotmail.com A +@print{} Becky 555-7685 becky.algebrarum@@gmail.com A +@print{} Bill 555-1675 bill.drowning@@hotmail.com A +@print{} Camilla 555-2912 camilla.infusarum@@skynet.be R +@print{} Fabius 555-1234 fabius.undevicesimus@@ucb.edu F +@print{} Martin 555-6480 martin.codicibus@@hotmail.com A +@print{} Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R +@end example + +@cindex @code{BEGIN}, criterio di ricerca, criteri di ricerca booleani e +@cindex @code{END}, criterio di ricerca, criteri di ricerca booleani e +@cindex @code{BEGINFILE}, criterio di ricerca, criteri di ricerca booleani e +@cindex @code{ENDFILE}, criterio di ricerca, criteri di ricerca booleani e +Le sottoespressioni di un'operatore booleano in un criterio di ricerca possono +essere espressioni regolari costanti, confronti, o qualsiasi altra espressione +di @command{awk}. Gli intervalli di ricerca +non sono espressioni, e quindi non possono apparire all'interno di +criteri di ricerca booleani. Analogamente, i criteri di ricerca speciali +@code{BEGIN}, @code{END}, @code{BEGINFILE} ed @code{ENDFILE}, +che non corrispondono ad alcun record in input, non sono espressioni e non +possono essere usati all'interno di criteri di ricerca booleani. + +L'ordine di precedenza dei differenti operatori che possono essere usati nei +criteri di ricerca @`e descritto in @ref{Precedenza}. + +@node Intervalli +@subsection Specificare intervalli di record con i criteri di ricerca + +@cindex intervalli di ricerca +@cindex criteri di ricerca, intervalli nei +@cindex righe, individuare intervalli di +@cindex @code{,} (virgola), negli intervalli di ricerca +@cindex virgola (@code{,}), negli intervalli di ricerca +Un @dfn{intervallo di ricerca} @`e composto da due criteri di ricerca +separati da una virgola, nella forma +@samp{@var{inizio_intervallo}, @var{fine_intervallo}}. @`E usato per +individuare +una serie di record consecutivi nei file in input. Il primo criterio di +ricerca, @var{inizio_intervallo}, controlla dove inizia la serie di record, +mentre @var{fine_intervallo} controlla dove finisce la serie stessa. +L'esempio seguente: + +@example +awk '$1 == "on", $1 == "off"' miofile +@end example + +@noindent +stampa ogni record in @file{miofile} incluso tra i due record che iniziano con +@samp{on}/@samp{off}, estremi compresi. + +Un intervallo di ricerca inizia con la valutazione di +@var{inizio_intervallo} per ogni record in input. Quando un record soddisfa +la condizione @var{inizio_intervallo}, l'intervallo di ricerca @`e +@dfn{attivato} e l'intervallo di ricerca include anche quel +record. Finch@'e l'intervallo di ricerca rimane attivo, +automaticamente vengono trovate corrispondenze in ogni record in input letto. +L'intervallo di ricerca verifica anche @var{fine_intervallo} per ogni +record in input; quando la verifica ha successo, il +criterio di ricerca viene @dfn{disattivato} a partire dal record seguente. +Quindi il criterio di ricerca torna a controllare +@var{inizio_intervallo} per ogni nuovo record. + +@cindex @code{if}, istruzione, azioni@comma{} modificabili +Il record che segnala l'inizio dell'intervallo +di ricerca e quello che segnala la fine di quell'intervallo soddisfano +@emph{entrambi} il criterio di ricerca. Se non si vuole agire su tali record +si possono scrivere istruzioni @code{if} nella parte @dfn{azione} della regola +per distinguerli dai record che il programma @`e interessato a trattare. + +@`E possibile che un criterio di ricerca sia attivato e disattivato dallo +stesso record. Se il record soddisfa entrambe le condizioni, l'azione @`e +eseguita solo su quel record. +Per esempio, si supponga che ci sia un testo tra due separatori identici +(p.es., il simbolo @samp{%}), ognuno dei quali sia su una riga a parte, che +dovrebbero essere ignorati. Un primo tentativo potrebbe essere quello di +combinare un intervallo di ricerca che descrive il +testo delimitato con l'istruzione +@code{next} +(non ancora introdotta, @pxref{Istruzione next}). +Con quest'istruzione @command{awk} non effettua alcuna azione sul record +corrente e inizia di nuovo a elaborare il successivo record in input. +Un tale programma @`e simile a questo: + +@example +/^%$/,/^%$/ @{ next @} + @{ print @} +@end example + +@noindent +@cindex righe, saltare tra delimitatori +@c @cindex @dfn{flag} variables +Questo programma non funziona, perch@'e l'intervallo di ricerca @`e sia attivato +che disattivato dalla prima riga incontrata, quella costituita da un @samp{%}. +Per ottenere l'effetto desiderato, si scriva il programma nella maniera che +segue, utilizzando un @dfn{flag}: + +@cindex @code{!} (punto esclamativo), operatore @code{!} +@cindex punto esclamativo (@code{!}), operatore @code{!} +@example +/^%$/ @{ ignora = ! ignora; next @} +ignora == 1 @{ next @} # ignora righe quando `ignora' @`e impostato a 1 +@end example + +In un intervallo di ricerca, la virgola (@samp{,}) ha la +precedenza pi@`u bassa tra tutti gli operatori (cio@`e, @`e l'ultima a essere +valutata). Il programma seguente tenta di combinare un intervallo di +ricerca con un altro controllo, pi@`u semplice: + +@example +echo Yes | awk '/1/,/2/ || /Yes/' +@end example + +L'intenzione in questo programma @`e quello di esprimere le condizioni +@samp{(/1/,/2/) || /Yes/}. +Tuttavia, @command{awk} lo interpreta come se fosse +@samp{/1/, (/2/ || /Yes/)}. +Questo comportamento non pu@`o essere cambiato o evitato; gli intervalli di +ricerca non si possono combinare con altri criteri di ricerca: + +@example +$ @kbd{echo Yes | gawk '(/1/,/2/) || /Yes/'} +@error{} gawk: riga com.:1: (/1/,/2/) || /Yes/ +@error{} gawk: riga com.:1: ^ syntax error +@end example + +@cindex intervalli di ricerca, continuazione di riga e +Come punto di secondaria importanza, nonostante sia stilisticamente poco elegante, +lo standard POSIX consente di andare a capo dopo la virgola +in un intervallo di ricerca. @value{DARKCORNER} +@node BEGIN/END +@subsection I criteri di ricerca speciali @code{BEGIN} ed @code{END} + +@cindex @code{BEGIN}, criterio di ricerca +@cindex @code{END}, criterio di ricerca +@cindex criterio di ricerca @code{END} +Tutti i criteri di ricerca fin qui descritti servono a individuare dei record +in input. +I criteri di ricerca speciali @code{BEGIN} ed @code{END} non hanno questo scopo. +Servono invece per effettuare azioni di inizializzazione o di pulizia nei +programmi @command{awk}. +Le regole @code{BEGIN} ed @code{END} devono prevedere azioni; non c'@`e +un'azione di default per queste regole, perch@'e non c'@`e un record corrente +quando sono invocate. +Le regole @code{BEGIN} ed @code{END} sono spesso chiamate +``blocchi @code{BEGIN} ed @code{END}'' da programmatori che usano @command{awk} +da molto tempo. + +@menu +* Usare BEGIN/END:: Come e perch@'e usare regole BEGIN/END. +* I/O e BEGIN/END:: Problemi di I/O nelle regole BEGIN/END. +@end menu + +@node Usare BEGIN/END +@subsubsection Azioni di inizializzazione e pulizia + +@cindex @code{BEGIN}, criterio di ricerca +@cindex criterio di ricerca @code{BEGIN} +@cindex @code{END}, criterio di ricerca +@cindex criterio di ricerca @code{END} +Una regola @code{BEGIN} @`e eseguita solo una volta, prima che sia letto il +primo record in input. Analogamente, una regola @code{END} @`e eseguita +solo una volta, dopo che tutto l'input @`e gi@`a stato letto. Per esempio: + +@example +$ @kbd{awk '} +> @kbd{BEGIN @{ print "Analisi di \"li\"" @}} +> @kbd{/li/ @{ ++n @}} +> @kbd{END @{ print "\"li\" @`e presente in", n, "record." @}' mail-list} +@print{} Analisi di "li" +@print{} "li" @`e presente in 4 record. +@end example + +@cindex @code{BEGIN}, criterio di ricerca, operatori e +@cindex @code{END}, criterio di ricerca, operatori e +@cindex criterio di ricerca @code{END}, operatori e +Questo programma trova il numero di record nel file in input +@file{mail-list} che contengono la stringa @samp{li}. La regola @code{BEGIN} +stampa un titolo per il rapporto. Non c'@`e bisogno di usare la regola +@code{BEGIN} per inizializzare il contatore @code{n} a zero, poich@'e +@command{awk} lo fa +automaticamente (@pxref{Variabili}). +La seconda regola incrementa la variabile @code{n} ogni volta che si legge +un record che soddisfa il criterio di ricerca @samp{li}. La regola @code{END} +stampa il valore di @code{n} alla fine del programma. + +I criteri di ricerca speciali @code{BEGIN} ed @code{END} non possono essere +usati negli intervalli, +o con operatori booleani (in effetti, non possono essere combinati con nessun +altro operatore). +Un programma @command{awk} pu@`o avere molte regole @code{BEGIN} e/o @code{END}. +Queste sono eseguite nell'ordine in cui compaiono nel programma: tutte le +regole @code{BEGIN} a inizio programma e tutte le regole @code{END} +a fine programma. +Le regole @code{BEGIN} ed @code{END} possono apparire in qualsiasi +posizione all'interno del programma. +Questa funzionalit@`a @`e stata aggiunta nella versione 1987 di @command{awk} ed +@`e inclusa nello standard POSIX. +La versione originale (1978) di @command{awk} richiedeva che la regola +@code{BEGIN} fosse posta all'inizio del programma, e la regola +@code{END} alla fine del programma, e solo una regola per tipo era ammessa. +Ci@`o non @`e pi@`u obbligatorio, ma @`e una buona idea continuare a seguire questo +modello per migliorare l'organizzazione e la leggibilit@`a del programma. + +Regole multiple @code{BEGIN} ed @code{END} sono utili per scrivere funzioni +di libreria, poich@'e ogni file di libreria pu@`o avere la sua propria regola +@code{BEGIN} e/o @code{END} per fare la propria inizializzazione e/o pulizia. +L'ordine in cui le funzioni di libreria sono menzionate nella riga dei comandi +determina l'ordine in cui le rispettive regole @code{BEGIN} ed @code{END} sono +eseguite. Per questo motivi, occorre prestare attenzione nello scrivere tali +regole nei file di libreria, in modo che non sia importante +l'ordine in cui tali regole vengono eseguite. +@xref{Opzioni} per maggiori informazioni sull'uso di funzioni di libreria. +@iftex +@xrefil{Funzioni di libreria}, +@end iftex +@ifnottex +@xref{Funzioni di libreria}, +@end ifnottex +per parecchie utili funzioni di libreria. + +Se un programma @command{awk} ha solo regole @code{BEGIN} e nessun'altra +regola, il programma esce dopo aver eseguito le regole +@code{BEGIN}.@footnote{La versione originale di @command{awk} continuava a +leggere e ignorare i record in input fino alla fine del file.} Tuttavia, se +una regola @code{END} esiste, l'intero input @`e letto, anche se non sono +presenti altre regole nel programma. Ci@`o viene fatto necessariamente +per permettere che +la regola @code{END} faccia uso delle variabili @code{FNR} e @code{NR}. + +@node I/O e BEGIN/END +@subsubsection Input/Output dalle regole @code{BEGIN} ed @code{END} + +@cindex input/output, dalle regole @code{BEGIN} ed @code{END} +Ci sono parecchi punti (talora insidiosi) da tener presente se si fa dell'I/O +all'interno di una regola @code{BEGIN} o @code{END}. +Il primo ha a che fare con il valore di @code{$0} in una regola @code{BEGIN}. +Poich@'e le regole @code{BEGIN} sono eseguite prima delle lettura di qualsiasi +input, non c'@`e assolutamente alcun record in input, e quindi nessun campo, +quando si eseguono delle regole @code{BEGIN}. I riferimento a @code{$0} e ai +campi restituiscono una stringa nulla o zero, a seconda del contesto. +Un modo per assegnare un valore effettivo a @code{$0} @`e di eseguire un +comando @code{getline} senza indicare una variabile (@pxref{Getline}). +Un altro modo @`e semplicemente quello di assegnare un valore a @code{$0}. + +@cindex Brian Kernighan, @command{awk} di +@cindex differenze tra @command{awk} e @command{gawk}, criteri di ricerca @code{BEGIN}/@code{END} +@cindex POSIX @command{awk}, criteri di ricerca @code{BEGIN}/@code{END} +@cindex @code{print}, istruzione, criteri di ricerca @code{BEGIN}/@code{END} e +@cindex @code{BEGIN}, criterio di ricerca, istruzione @code{print} e +@cindex @code{END}, criterio di ricerca, istruzione @code{print} e +Il secondo punto @`e simile al primo, ma in direzione opposta. +Tradizionalmente, pi@`u che altro per problemi di implementazione, @code{$0} +e @code{NF} erano @emph{indefiniti} all'interno di una regola @code{END}. +Lo standard POSIX prescrive che @code{NF} sia disponibile all'interno di una +regola @code{END}. Contiene il numero di campi dell'ultimo record in input. +Probabilmente per una svista, lo standard non specifica che @`e reso +disponibile anche @code{$0}, sebbene possa apparire logico che sia cos@`{@dotless{i}}. +In effetti, BWK @command{awk}, @command{mawk} e @command{gawk} mantengono il +valore di @code{$0} in modo che sia possibile usarlo all'interno delle regole +@code{END}. Occorre peraltro tener presente che alcune altre implementazioni +e parecchie tra le versioni pi@`u vecchie di Unix @command{awk} non si +comportano cos@`{@dotless{i}}. + +Il terzo punto @`e una conseguenza dei primi due. Il significato di +@samp{print} +all'interno di una regola @code{BEGIN} o @code{END} @`e quello di sempre: +@samp{print $0}. Se @code{$0} @`e la stringa nulla, stampa una riga vuota. +Molti programmatori di lungo corso di @command{awk} usano un semplice +@samp{print} all'interno delle regole @code{BEGIN} ed @code{END}, +intendendo @samp{@w{print ""}}, contando sul fatto che @code{$0} sia una +stringa nulla. Sebbene questo funzioni solitamente con le regole +@code{BEGIN}, @`e una pessima idea nelle regole @code{END}, +almeno in @command{gawk}. @`E anche stilisticamente inelegante, perch@'e se +serve una riga vuota in output, il programma dovrebbe stamparne +una esplicitamente. + +@cindex @code{next}, istruzione, criteri di ricerca @code{BEGIN}/@code{END} e +@cindex @code{nextfile}, istruzione, criteri di ricerca @code{BEGIN}/@code{END} e +@cindex @code{BEGIN}, criterio di ricerca, istruzioni @code{next}/@code{nextfile} e +@cindex @code{END}, criterio di ricerca, istruzioni @code{next}/@code{nextfile} e +Per finire, le istruzioni @code{next} e @code{nextfile} non sono consentite +all'interno di una regola @code{BEGIN}, perch@'e il ciclo implicito +leggi-un-record-e-confrontalo-con-le-regole non @`e ancora iniziato. +Analogamente, tali istruzioni non sono valide all'interno di una regola +@code{END}, perch@'e tutto l'input @`e gi@`a stato letto. +(@xref{Istruzione next} e +@ifnotdocbook +@pxref{Istruzione nextfile}.) +@end ifnotdocbook +@ifdocbook +@ref{Istruzione nextfile}.) +@end ifdocbook + +@node BEGINFILE/ENDFILE +@subsection I criteri di ricerca speciali @code{BEGINFILE} ed @code{ENDFILE} +@cindex @code{BEGINFILE}, criterio di ricerca +@cindex @code{ENDFILE}, criterio di ricerca +@cindex differenze tra @command{awk} e @command{gawk}, criteri di ricerca @code{BEGINFILE}/@code{ENDFILE} + +Questa @value{SECTION} descrive una funzionalit@`a specifica di @command{gawk}. + +Due tipi speciali di criterio di ricerca, @code{BEGINFILE} ed @code{ENDFILE}, +forniscono +degli ``agganci'' per intervenire durante il ciclo di elaborazione dei file +specificati sulla riga di comando di @command{gawk}. +Come con le regole @code{BEGIN} ed @code{END} +@ifnottex +@ifnotdocbook +(@pxref{BEGIN/END}), +@end ifnotdocbook +@end ifnottex +@iftex +(si veda la @value{SECTION} precedente), +@end iftex +@ifdocbook +(si veda la @value{SECTION} precedente), +@end ifdocbook +tutte le regole @code{BEGINFILE} in un programma sono riunite, mantenendole +nell'ordine in cui sono lette da @command{gawk} e lo stesso viene fatto +per tutte le regole @code{ENDFILE}. + +Il corpo delle regole @code{BEGINFILE} @`e eseguito subito prima che +@command{gawk} legga il primo record da un file. La variabile @code{FILENAME} +@`e impostata al nome del file corrente e @code{FNR} @`e impostata a zero. + +La regola @code{BEGINFILE} d@`a la possibilit@`a di eseguire due compiti +che sarebbe difficile o impossibile effettuare altrimenti: + +@itemize @value{BULLET} +@item +Si pu@`o verificare che il file sia leggibile. Di solito, se un file presente +nella riga dei comandi non pu@`o essere aperto in lettura, il programma +@command{gawk} viene terminato. Comunque, questo si pu@`o evitare, per poi +passare a elaborare il file successivo specificato sulla riga dei comandi. + +@cindex @command{gawk}, variabile @code{ERRNO} in +@cindex @code{ERRNO}, variabile, con criterio di ricerca @code{BEGINFILE} +@cindex @code{nextfile}, istruzione, criteri di ricerca @code{BEGINFILE}/@code{ENDFILE} e +Questo controllo @`e fattibile controllando se la variabile @code{ERRNO} @`e +diversa dalla stringa nulla; se @`e questo il caso, @command{gawk} non @`e +riuscito ad aprire il file. In questo caso il programma pu@`o eseguire +un'istruzione @code{nextfile} +(@pxref{Istruzione nextfile}). In questo modo @command{gawk} salta +completamente l'elaborazione di quel file. +In caso contrario, @command{gawk} termina come al solito con un +errore fatale. + +@item +Se sono state scritte estensioni che modificano la gestione del record +(tramite l'inserzione di un ``analizzatore di input''; +@pxref{Analizzatori di input}), @`e possibile richiamarle +a questo punto, prima che @command{gawk} inizi a elaborare il file. +(Questa @`e una funzionalit@`a @emph{molto} avanzata, usata al momento solo dal +@uref{http://sourceforge.net/projects/gawkextlib, progetto @code{gawkextlib}}.) +@end itemize + +La regola @code{ENDFILE} @`e chiamata quando @command{gawk} ha finito di +elaborare l'ultimo record di un file in input. Per l'ultimo file in input, +@`e chiamata prima di ogni regola @code{END}. +La regola @code{ENDFILE} @`e eseguita anche per file in input vuoti. + +Normalmente, se si verifica un errore di lettura durante il normale +ciclo di elaborazione dell'input, +questo @`e considerato fatale (il programma termina). Tuttavia, se @`e presente +una regola @code{ENDFILE}, l'errore non @`e considerato fatale, ma viene +impostato @code{ERRNO}. Ci@`o permette di intercettare ed elaborare errori +di I/O a livello di programma @command{awk}. + +@cindex @code{next}, istruzione, criteri di ricerca @code{BEGINFILE}/@code{ENDFILE} e +L'istruzione @code{next} (@pxref{Istruzione next}) non @`e permessa all'interno +di una regola @code{BEGINFILE} o @code{ENDFILE}. L'istruzione @code{nextfile} +@`e consentita solo all'interno di una regola @code{BEGINFILE}, non all'interno +di una regola @code{ENDFILE}. + +@cindex @code{getline}, comando, criteri di ricerca @code{BEGINFILE}/@code{ENDFILE} e +L'istruzione @code{getline} (@pxref{Getline}) @`e limitata all'interno sia di +@code{BEGINFILE} che di @code{ENDFILE}: solo le forme ridirette di +di @code{getline} sono permesse. + +@code{BEGINFILE} ed @code{ENDFILE} sono estensioni @command{gawk}. +In molte altre implementazioni di @command{awk} o se @command{gawk} @`e in +modalit@`a compatibile (@pxref{Opzioni}), non sono regole speciali. + +@c FIXME: For 4.2 maybe deal with this? +@ignore +Date: Tue, 17 May 2011 02:06:10 PDT +From: rankin@pactechdata.com (Pat Rankin) +Message-Id: <110517015127.20240f4a@pactechdata.com> +Subject: BEGINFILE +To: arnold@skeeve.com + + The documentation for BEGINFILE states that FNR is 0, which seems +pretty obvious. It doesn't mention what the value of $0 is, and that's +not obvious. I think setting it to null before starting the BEGINFILE +action would be preferable to leaving whatever was there in the last +record of the previous file. + + ENDFILE can retain the last record in $0. I guess it has to if +the END rule's actions see that value too. But the beginning of a new +file doesn't just mean that the old one has been closed; the old file +is being superseded, so leaving the old data around feels wrong to me. +[If the user wants to keep it on hand, he or she can use an ENDFILE +rule to grab it before moving on to the next file.] +@end ignore + +@node Vuoto +@subsection Il criterio di ricerca vuoto + +@cindex vuoto, criterio di ricerca +@cindex criteri di ricerca vuoti +Un criterio di ricerca vuoto (cio@`e omesso) corrisponde a +@emph{ogni} record in input. Per esempio, il programma: + +@example +awk '@{ print $1 @}' mail-list +@end example + +@noindent +stampa il primo campo di ogni record. + +@node Usare variabili di shell +@section Usare variabili di shell in programmi +@cindex shell, variabili di +@cindex programmi @command{awk}, variabili di shell in +@c @cindex shell and @command{awk} interaction + +I programmi @command{awk} sono spesso usati come componenti di programmi pi@`u +ampi, scritti in un linguaggio di shell. +Per esempio, @`e molto comune usare una variabile di shell per +specificare un criterio di ricerca che il programma @command{awk} deve poi +individuare. +Ci sono due modi per rendere disponibile il valore di una variabile di shell +all'interno di un programma @command{awk}. + +@cindex shell, uso di doppio apice +Un modo comune @`e quello di usare i doppi apici per sostituire il valore della +variabile nel progamma @command{awk} contenuto nello @dfn{script}: + +Per esempio, si consideri il programma seguente: + +@example +printf "Immettere il criterio di ricerca: " +read criterio_di_ricerca +awk "/$criterio_di_ricerca/ "'@{ num_trov++ @} + END @{ print num_trov, "occorrenze trovate" @}' /nome/file/dati +@end example + +@noindent +Il programma @command{awk} consiste di due pezzi di testo tra apici +che, concatenati insieme, formano il programma. +La prima parte @`e tra doppi apici, per consentire la sostituzione della +variabile di shell @code{criterio_di_ricerca} contenuta al loro interno. +La seconda parte @`e racchiusa tra apici singoli. + +La sostituzione di variabile attraverso gli apici funziona, ma pu@`o +facilmente generare difficolt@`a. Richiede una buona comprensione delle +regole per l'uso degli apici nella shell +(@pxref{Protezione}), +e spesso @`e difficile accoppiare i vari apici quando si legge il programma. + +Un metodo migliore @`e quello di usare la funzionalit@`a di assegnamento delle +variabili di @command{awk} +(@pxref{Opzioni di assegnamento}) +per assegnare il valore di una variabile di shell a una variabile +di @command{awk}. +Poi si possono usare @dfn{regexp} dinamiche come criterio di ricerca +(@pxref{Espressioni regolari calcolate}). +Quanto segue mostra come sarebbe l'esempio precedente usando questa tecnica: + +@example +printf "Immettere il criterio di ricerca: " +read criterio_di_ricerca +awk -v crit="$criterio_di_ricerca" '$0 ~ crit @{ num_trov++ @} + END @{ print num_trov, "occorrenze trovate" @}' /nome/file/dati +@end example + +@noindent +Adesso il programma @command{awk} @`e solo una stringa tra apici semplici. +L'assegnamento @samp{-v crit="$criterio_di_ricerca"} richiede ancora doppi +apici, per il caso in cui uno spazio vuoto sia presente nel valore di +@code{$criterio_di_ricerca}. +La variabile @command{awk} @code{crit} potrebbe avere come nome anche +@code{criterio_di_ricerca}, ma ci@`o potrebbe essere causa di confusione. +Usare una variabile permette una maggiore flessibilit@`a, poich@'e la variabile +pu@`o essere usata in ogni parte del +programma---per stamparla, per indicizzare un vettore, o per qualsiasi altro +scopo---senza che sia necessario l'artificio di doverla inserire usando gli +apici. + +@node Panoramica sulle azioni +@section Azioni +@c @cindex action, definition of +@c @cindex curly braces +@c @cindex action, curly braces +@c @cindex action, separating statements +@cindex azioni + +Un programma o script @command{awk} consiste in una serie di +regole e definizioni di funzione frammiste tra loro. (Le funzioni sono +descritte pi@`u avanti. @xref{Funzioni definite dall'utente}.) +Una regola contiene un criterio di ricerca e un'azione; l'uno o l'altra +(ma non tutt'e due) possono essere omessi. Lo scopo di una @dfn{azione} @`e +di specificare cosa deve fare @command{awk} quando si trova una corrispondenza +con il criterio di ricerca. Quindi, schematicamente, un programma +@command{awk} @`e normalmente simile a questo: + +@display +[@var{criterio di ricerca}] @code{@{ @var{azione} @}} + @var{criterio di ricerca} [@code{@{ @var{azione} @}}] +@dots{} +@code{function @var{nome}(@var{argomenti}) @{ @dots{} @}} +@dots{} +@end display + +@cindex @code{@{@}} (parentesi graffe), azioni e +@cindex parentesi graffe (@code{@{@}}), azioni e +@cindex separatori, per istruzioni in azioni +@cindex a capo, separatore di istruzioni nelle azioni +@cindex @code{;} (punto e virgola), separare istruzioni nelle azioni +@cindex punto e virgola (@code{;}), separare istruzioni nelle azioni +Un'azione consiste di una o pi@`u @dfn{istruzioni} @command{awk}, racchiuse +fra parentesi graffe (@samp{@{@r{@dots{}}@}}). Ogni istruzione specifica +una cosa da fare. Le istruzioni sono separate tra loro da dei ritorni a capo o +da dei punti e virgola. +Le parentesi graffe attorno a un'azione vanno usate anche se l'azione +contiene una sola istruzione o se non contiene alcuna istruzione. +Comunque, se si omette completamente l'azione, si possono omettere anche le +parentesi graffe. Un'azione omessa @`e equivalente a specificare +@samp{@{ print $0 @}}: + +@example +/pippo/ @{ @} @ii{se si trova @code{pippo}, non fare nulla --- azione vuota} +/pippo/ @ii{se si trova @code{pippo}, stampa il record --- azione omessa} +@end example + +I seguenti tipi di istruzione sono disponibili in @command{awk}: + +@table @asis +@cindex effetti collaterali delle istruzioni +@cindex istruzioni, effetti collaterali delle +@item Espressioni +Servono per chiamare funzioni o assegnare valori a variabili +@iftex +(@pxrefil{Espressioni}). L'esecuzione +@end iftex +@ifnottex +(@pxref{Espressioni}). L'esecuzione +@end ifnottex +di questo tipo di istruzione calcola semplicemente il valore dell'espressione. +Ci@`o @`e utile quando l'espressione ha effetti collaterali +(@pxref{Operatori di assegnamento}). + +@item Istruzioni di controllo +Specificano il flusso di controllo dei programmi @command{awk}. +Il linguaggio @command{awk} utilizza dei costrutti simili a quelli del C, +(@code{if}, @code{for}, @code{while} e @code{do}), e anche alcune altre +di tipo speciale (@pxref{Istruzioni}). + +@item Istruzioni composte +Sono una o pi@`u istruzioni racchiuse tra parentesi graffe. Un'istruzione +composta +@`e usata per riunire un gruppo di istruzioni all'interno di +un'istruzione @code{if}, @code{while}, @code{do} o @code{for}. + +@item Istruzioni di input +Usano il comando @code{getline} +(@pxref{Getline}). +In @command{awk} sono anche disponibili le istruzioni @code{next} +(@pxref{Istruzione next}) +e @code{nextfile} +(@pxref{Istruzione nextfile}). + +@item Istruzioni di output +Come @code{print} e @code{printf}. +@iftex +@xrefIl{Stampare}. +@end iftex +@ifnottex +@xref{Stampare}. +@end ifnottex + +@item Istruzioni di cancellazione +Per eliminare elementi di vettori. +@xref{Cancellazione}. +@end table + +@node Istruzioni +@section Istruzioni di controllo nelle azioni +@cindex istruzioni di controllo +@cindex controllo, tramite istruzioni, in azioni +@cindex azioni, istruzioni di controllo in + +Le @dfn{istruzioni di controllo}, come @code{if}, @code{while} e cos@`{@dotless{i}} via, +regolano il flusso di esecuzione nei programmi @command{awk}. Molte tra +le istruzioni di controllo di @command{awk} sono modellate sulle +corrispondenti istruzioni in C. +@cindex istruzioni composte@comma{} istruzioni di controllo e +@cindex composte, istruzioni@comma{} istruzioni di controllo e +@cindex corpo, nelle azioni +@cindex @code{@{@}} (parentesi graffe), istruzioni, raggruppare +@cindex parentesi graffe (@code{@{@}}), istruzioni, raggruppare +@cindex a capo, separatore di istruzioni nelle azioni +@cindex @code{;} (punto e virgola), separare istruzioni nelle azioni +@cindex punto e virgola (@code{;}), separare istruzioni nelle azioni +Tutte le istruzioni di controllo iniziano con parole chiave speciali, come +@code{if} e @code{while}, per distinguerle dalle semplici espressioni. +Molte istruzioni di controllo contengono altre istruzioni. Per esempio, +l'istruzione @code{if} contiene un'altra istruzione che pu@`o essere eseguita +oppure no. Le istruzioni contenute sono chiamate @dfn{corpo}. +Per includere pi@`u di un'istruzione nel corpo, queste vanno raggruppate +in una sola @dfn{istruzione composta} tra parentesi graffe, e separate tra +loro con dei ritorni a capo o dei punti e virgola. + +@menu +* Istruzione if:: Eseguire in maniera condizionale + istruzioni @command{awk}. +* Istruzione while:: Eseguire il ciclo finch@'e @`e + verificata una condizione. +* Istruzione do:: Eseguire l'azione specificata, continuare + a eseguire il ciclo + finch@'e @`e verificata una condizione. +* Istruzione for:: Un'altra istruzione iterativa, che + permette di specificare clausole + iniziali e di incremento. +* Istruzione switch :: Valutazione di quale insieme di + istruzioni eseguire, a seconda del + valore assunto da una variabile. +* Istruzione break:: Uscire subito dal ciclo pi@`u interno + in cui ci si trova. +* Istruzione continue:: Andare alla fine del ciclo pi@`u interno + in cui ci si trova. +* Istruzione next:: Smettere di elaborare il record corrente. +* Istruzione nextfile:: Smettere di elaborare il file corrente. +* Istruzione exit:: Interrompere l'esecuzione di @command{awk}. +@end menu + +@node Istruzione if +@subsection L'istruzione @code{if}-@code{else} + +@cindex istruzione @code{if} +@cindex @code{if}, istruzione +L'istruzione @code{if}-@code{else} @`e quella che serve in @command{awk} +per prendere decisioni. @`E simile +a questa: + +@display +@code{if (@var{condizione}) @var{se-vera-fai}} [@code{else @var{se-falsa-fai}}] +@end display + +@noindent +La @var{condizione} @`e un'espressione che controlla quel che fa il resto +dell'istruzione. Se la @var{condizione} @`e vera, viene eseguita la +parte @var{se-vera-fai}; altrimenti viene +eseguita la parte @var{se-falsa-fai}. +La parte @code{else} dell'istruzione @`e +facoltativa. La condizione @`e considerata falsa se il suo valore @`e zero o +la stringa nulla; altrimenti, la condizione @`e vera. +Si consideri quanto segue: + +@example +if (x % 2 == 0) + print "x @`e pari" +else + print "x @`e dispari" +@end example + +In questo esempio, se l'espressione @samp{x % 2 == 0} @`e vera (cio@`e, +se il valore di @code{x} @`e esattamente divisibile per due), allora viene +eseguita la prima istruzione +@code{print}; altrimenti, viene eseguita la seconda istruzione @code{print}. +Se la parola chiave @code{else} sta sulla stessa riga di @var{se-vera-fai} +e se @var{se-vera-fai} non @`e un'istruzione composta (cio@`e, non @`e racchiusa +tra parentesi graffe), allora un punto e virgola deve separare +@var{se-vera-fai} dalla parola chiave @code{else}. +Per chiarire questo, l'esempio precedente si pu@`o riscrivere come: + +@example +if (x % 2 == 0) print "x @`e pari"; else + print "x @`e dispari" +@end example + +@noindent +Se il @samp{;} @`e omesso, @command{awk} non pu@`o interpretare l'istruzione e +segnala un errore di sintassi. Non si dovrebbero scrivere programmi in +questo modo, perch@'e a chi li legge potrebbe sfuggire la parola chiave +@code{else} se non @`e la prima parola della riga. + +@node Istruzione while +@subsection L'istruzione @code{while} +@cindex @code{while}, istruzione +@cindex istruzione @code{while} +@cindex cicli +@cindex cicli, @code{while} +@cindex cicli, si veda anche @code{while}, istruzione + +Nella programmazione, un @dfn{ciclo} @`e una parte di un programma che pu@`o +essere eseguita due o pi@`u volte consecutivamente. +L'istruzione @code{while} @`e la pi@`u semplice istruzione iterativa in +@command{awk}. Esegue ripetutamente un'istruzione finch@'e una data +condizione @`e vera. Per esempio: + +@example +while (@var{condizione}) + @var{corpo-del-ciclo} +@end example + +@cindex corpo, nei cicli +@noindent +@var{corpo-del-ciclo} @`e un'istruzione detta @dfn{corpo} del ciclo, +e @var{condizione} @`e un'espressione che controlla per quante volte il ciclo +deve continuare a essere ripetuto. +La prima cosa che l'istruzione @code{while} fa @`e un controllo della +@var{condizione}. +Se la @var{condizione} @`e vera, viene eseguita l'istruzione +@var{corpo-del-ciclo}. +@ifinfo +(La @var{condizione} @`e vera quando il suo valore +@`e diverso da zero e non @`e la stringa nulla.) +@end ifinfo +Dopo che le istruzioni in @var{corpo-del-ciclo} sono state eseguite, +@var{condizione} @`e controllata nuovamente, e se @`e ancora vera, +@var{corpo-del-ciclo} viene eseguito ancora. Questo processo @`e ripetuto +finch@'e @var{condizione} rimane vera. Se la @var{condizione} @`e falsa fin +dall'inizio, il corpo del ciclo +non viene eseguito per nulla, e @command{awk} continua con l'istruzione +che viene dopo il ciclo. +Questo esempio stampa i primi tre campi di ogni record in input, uno per +riga: + +@example +awk ' +@{ + i = 1 + while (i <= 3) @{ + print $i + i++ + @} +@}' inventory-shipped +@end example + +@noindent +Il corpo di questo ciclo @`e un'istruzione composta racchiusa tra parentesi graffe, +che contiene due istruzioni. +Il ciclo funziona in questo modo: all'inizio, il valore di @code{i} @`e +impostato a 1. +Poi, l'istruzione @code{while} controlla se @code{i} @`e minore o uguale a +tre. Ci@`o @`e vero quando @code{i} @`e uguale a 1, quindi il campo +@code{i}-esimo viene stampato. Quindi l'istruzione @samp{i++} incrementa il +valore di @code{i} +e il ciclo viene ripetuto. Il ciclo termina quando @code{i} assume il +valore quattro. + +Un ritorno a capo non @`e richiesto tra la condizione e il corpo del ciclo; +tuttavia, se lo si mette, il programma @`e di pi@`u facile comprensione, +a meno che il corpo del ciclo non sia un'istruzione composta, oppure se @`e +qualcosa di molto semplice. Neppure il ritorno a capo dopo la parentesi graffa +aperta che inizia l'istruzione composta @`e necessario, ma il +programma @`e di lettura pi@`u difficile se lo si omette. + +@node Istruzione do +@subsection L'istruzione @code{do}-@code{while} +@cindex @code{do}-@code{while} +@cindex cicli, @code{do}-@code{while} + +Il ciclo @code{do} @`e una variazione dell'istruzione di ciclo @code{while}. +Il ciclo @code{do} esegue il @var{corpo-del-ciclo} una volta e poi ripete il +@var{corpo-del-ciclo} finch@'e la @var{condizione} rimane vera. @`E simile a questo: +@example +do + @var{corpo-del-ciclo} +while (@var{condizione}) +@end example + +Anche se la @var{condizione} @`e falsa fin dall'inizio, il @var{corpo-del-ciclo} +viene eseguito almeno una volta (e solo una volta, a meno che +l'esecuzione di @var{corpo-del-ciclo} +non renda vera la @var{condizione}). Si confronti con il corrispondente +@code{while}: + +@example +while (@var{condizione}) + @var{corpo-del-ciclo} +@end example + +@noindent +Quest'istruzione non esegue il @var{corpo-del-ciclo} neppure una volta, se +la @var{condizione} @`e falsa fin dall'inizio. Il seguente @`e un esempio di +@code{do}: + +@example +@{ + i = 1 + do @{ + print $0 + i++ + @} while (i <= 10) +@} +@end example + +@noindent +Questo programma stampa ogni record in input per 10 volte. Non si tratta, +peraltro, di un esempio molto realistico, perch@'e in questo caso un semplice +@code{while} sarebbe sufficiente. Questa osservazione riflette un'esperienza +reale; solo occasionalmente @`e davvero necessario usare un @code{do}. + +@node Istruzione for +@subsection L'istruzione @code{for} +@cindex istruzione @code{for} +@cindex @code{for}, istruzione +@cindex cicli, @code{for}, iterativi + +L'istruzione @code{for} rende pi@`u agevole contare le iterazioni di un ciclo. +La forma generale dell'istruzione @code{for} @`e simile a questa: + +@example +for (@var{inizializzazione}; @var{condizione}; @var{incremento}) + @var{corpo-del-ciclo} +@end example + +@noindent +La parti @var{inizializzazione}, @var{condizione} e @var{incremento} sono +espressioni @command{awk} a piacere, e @var{corpo-del-ciclo} indica qualsiasi +istruzione @command{awk}. + +L'istruzione @code{for} comincia con l'esecuzione di @var{inizializzazione}. +Poi, finch@'e +la @var{condizione} @`e vera, esegue ripetutamente @var{corpo-del-ciclo}, +e quindi @var{incremento}. Tipicamente, @var{inizializzazione} imposta una +variabile a zero o a uno, @var{incremento} aggiunge uno alla stessa e +@var{condizione} ne confronta il valore rispetto al numero desiderato di +iterazioni. +Per esempio: + +@example +awk ' +@{ + for (i = 1; i <= 3; i++) + print $i +@}' inventory-shipped +@end example + +@noindent +Questo programma stampa i primi tre campi di ogni record in input, mettendo +un campo su ogni riga. + +Non @`e possibile impostare +pi@`u di una variabile nella parte di +@var{inizializzazione} senza usare un'istruzione di assegnamento multiplo, +come @samp{x = y = 0}. Ci@`o ha senso solo se tutti i valori iniziali +sono uguali. (Ma @`e possibile inizializzare ulteriori variabili scrivendo +i relativi assegnamenti come istruzioni separate @emph{prima} del ciclo +@code{for}.) + +@c @cindex comma operator, not supported +Lo stesso vale per la parte @var{incremento}. Se serve incrementare ulteriori +variabili, questo va fatto con istruzioni separate alla fine del ciclo. +L'espressione composta del linguaggio C, che usa l'operatore virgola [,] +del C, sarebbe +utile in questo contesto, ma non @`e +prevista in @command{awk}. + +Molto spesso, @var{incremento} @`e un'espressione di incremento, come +nell'esempio precedente. Ma questo non @`e obbligatorio; pu@`o trattarsi di +un'espressione qualsiasi. Per esempio, +la seguente istruzione stampa tutte le potenze di due comprese +tra 1 e 100: + +@example +for (i = 1; i <= 100; i *= 2) + print i +@end example + +Se non @`e necessaria, ognuna delle tre espressioni fra +parentesi che segue la parola chiave @code{for} pu@`o essere omessa. Quindi, +@w{@samp{for (; x > 0;)}} @`e equivalente a @w{@samp{while (x > 0)}}. Se la +@var{condizione} @`e omessa del tutto, @`e ritenuta sempre vera, producendo +un @dfn{ciclo infinito} (cio@`e, un ciclo che non finisce mai). + +Molto spesso, un ciclo @code{for} @`e un'abbreviazione per un ciclo @code{while}, +come si pu@`o vedere qui: + +@example +@var{inizializzazione} +while (@var{condizione}) @{ + @var{corpo-del-ciclo} + @var{incremento} +@} +@end example + +@cindex cicli, istruzione @code{continue} e +@noindent +La sola eccezione @`e quando l'istruzione @code{continue} +(@pxref{Istruzione continue}) @`e usata +all'interno del ciclo. Se si modifica un'istruzione @code{for} +sostituendola con un'istruzione @code{while} +ci@`o pu@`o cambiare l'effetto dell'istruzione @code{continue} posta all'interno +del ciclo. + +Il linguaggio @command{awk} ha un'istruzione @code{for} oltre all'istruzione +@code{while} perch@'e un ciclo @code{for} @`e spesso pi@`u semplice da scrivere, +e viene in mente pi@`u naturalmente. +Contare il numero di iterazioni @`e +molto frequente nei cicli. Pu@`o essere pi@`u facile pensare a questo conto come +parte del ciclo, piuttosto che come qualcosa da fare all'interno del ciclo. + +@cindex @code{in}, operatore +@cindex operatore @code{in} +Esiste una versione alternativa al ciclo @code{for}, per esaminare tutti +gli indici di un vettore: + +@example +for (i in vettore) + @var{fai qualcosa con} vettore[i] +@end example + +@noindent +@xref{Visitare un intero vettore} +per maggiori informazioni su questa versione del ciclo @code{for}. + +@node Istruzione switch +@subsection L'istruzione @code{switch} +@cindex @code{switch}, istruzione +@cindex @code{case}, parola chiave +@cindex parola chiave @code{case} +@cindex @code{default}, parola chiave +@cindex parola chiave @code{default} + +Questa @value{SECTION} descrive una funzionalit@`a disponibile solo in +@command{gawk}. +Se @command{gawk} @`e in modalit@`a compatibile (@pxref{Opzioni}), +la funzionalit@`a non @`e disponibile. + +L'istruzione @code{switch} consente di valutare un'espressione e di +eseguire istruzioni se il valore trovato corrisponde a uno dei @code{case} [casi] previsti. +Le istruzioni @code{case} sono esaminate per cercare una corrispondenza +nell'ordine in cui i casi sono definiti nel programma. Se nessuno dei @code{case} +corrisponde al valore dell'espressione, viene eseguita la sezione +@code{default}, se @`e stata specificata. + +Ogni @code{case} contiene una singola costante, che pu@`o essere un numero, +una stringa, o +una @dfn{regexp}. Viene valutata l'espressione @code{switch}, e poi la +costante di ogni @code{case} viene confrontata +di volta in volta con il valore risultante. +Il tipo di costante determina quale sar@`a il confronto: per i tipi numerici o +stringa si seguono le regole abituali. Per una costante @dfn{regexp} viene +effettuato un confronto tra l'espressione e il valore di tipo stringa +dell'espressione originale. +Il formato generale dell'istruzione @code{switch} @`e simile a questo: + +@example +switch (@var{espressione}) @{ +case @var{valore o espressione regolare}: + @var{corpo-del-caso} +default: + @var{corpo-del-default} +@} +@end example + +Il flusso di controllo +dell'istruzione @code{switch} funziona come per il linguaggio C. Una volta +stabilita una corrispondenza con un dato caso, le istruzione che formano il +corpo del caso sono eseguite, fino a che non venga trovata un'istruzione +@code{break}, +@code{continue}, @code{next}, @code{nextfile} o @code{exit}, +o fino alla fine dell'istruzione @code{switch} medesima. Per esempio: + +@example +while ((c = getopt(ARGC, ARGV, "aksx")) != -1) @{ + switch (c) @{ + case "a": + # stampa la dimensione di tutti i file + all_files = TRUE; + break + case "k": + BLOCK_SIZE = 1024 # in blocchi da 1 Kbyte + break + case "s": + # fa solo le somme + sum_only = TRUE + break + case "x": + # non esce dal filesystem + fts_flags = or(fts_flags, FTS_XDEV) + break + case "?": + default: + uso() + break + @} +@} +@end example + +Si noti che se nessuna delle istruzioni specificate qui arresta l'esecuzione +di un'istruzione @code{case} per la quale @`e stata trovata una corrispondenza; +l'esecuzione continua fino al successivo @code{case} finch@'e +non viene interrotta. In questo esempio, il +@code{case} per @code{"?"} esegue quello di @code{default}, che consiste nel +chiamare una funzione di nome @code{uso()}. +(La funzione @code{getopt()} qui chiamata @`e descritta in +@ref{Funzione getopt}.) + +@node Istruzione break +@subsection L'istruzione @code{break} +@cindex @code{break}, istruzione +@cindex istruzione @code{break} +@cindex cicli, uscita +@cindex cicli, istruzione @code{break} e + +L'istruzione @code{break} esce dal ciclo pi@`u interno @code{for}, +@code{while} o @code{do} dentro al quale si trova. L'esempio seguente +trova, se esiste, il divisore pi@`u piccolo di un dato numero intero, oppure +dichiara che si tratta di un numero primo: + +@example +# trova il divisore pi@`u piccolo di num +@{ + num = $1 + for (divisore = 2; divisore * divisore <= num; divisore++) @{ + if (num % divisore == 0) + break + @} + if (num % divisore == 0) + printf "Il pi@`u piccolo divisore di %d @`e %d\n", num, divisore + else + printf "%d @`e un numero primo\n", num +@} +@end example + +Quando il resto della divisione @`e zero nella prima istruzione @code{if}, +@command{awk} immediatamente esce, a causa del @dfn{break}, dal ciclo +@code{for} in cui @`e contenuto. Ci@`o vuol dire +che @command{awk} prosegue immediatamente fino all'istruzione che viene dopo +il ciclo, e continua l'elaborazione. (L'istruzione @code{break} @`e molto +differente dall'istruzione @code{exit}, +la quale termina l'intero programma @command{awk}. +@xref{Istruzione exit}.) + +Il seguente programma mostra come la @var{condizione} di un'istruzione +@code{for} o @code{while} potrebbe essere sostituita da un'istruzione +@code{break} all'interno di un @code{if}: + +@example +# trova il divisore pi@`u piccolo di num +@{ + num = $1 + for (divisore = 2; ; divisore++) @{ + if (num % divisore == 0) @{ + printf "Il pi@`u piccolo divisore di %d @`e %d\n", num, divisore + break + @} + if (divisore * divisore > num) @{ + printf "%d @`e un numero primo\n", num + break + @} + @} +@} +@end example + +L'istruzione @code{break} @`e usata anche per terminare l'esecuzione di +un'istruzione @code{switch}. +Questo argomento @`e trattato in @ref{Istruzione switch}. + +@c @cindex @code{break}, outside of loops +@c @cindex historical features +@c @cindex @command{awk} language, POSIX version +@cindex POSIX @command{awk}, @code{break} e +@cindex angolo buio, istruzione @code{break} +@cindex @command{gawk}, istruzione @code{break} in +@cindex Brian Kernighan, @command{awk} di +L'istruzione @code{break} non ha significato se +usata fuori dal corpo di un ciclo o di un'istruzione @code{switch}. +Tuttavia, anche se la cosa non @`e mai stata documentata, +le prime implementazioni di @command{awk} consideravano l'istruzione @code{break} +esterna a un ciclo come un'istruzione @code{next} +(@pxref{Istruzione next}). +@value{DARKCORNER} +Versioni recenti di BWK @command{awk} non consentono pi@`u un tale uso, +e lo stesso fa @command{gawk}. + +@node Istruzione continue +@subsection L'istruzione @code{continue} + +@cindex @code{continue}, istruzione +@cindex istruzione @code{continue} +Analogamente a @code{break}, l'istruzione @code{continue} @`e usata solo +all'interno di cicli @code{for}, @code{while} e @code{do}. L'istruzione +ignora il resto del corpo del ciclo, facendo s@`{@dotless{i}} che la successiva iterazione +del ciclo inizi immediatamente. Questo comportamento @`e differente da quello +di @code{break}, che esce completamente dal ciclo. + +L'istruzione @code{continue} in un ciclo @code{for} fa s@`{@dotless{i}} che @command{awk} +ignori il resto del corpo del ciclo e prosegua l'esecuzione con l'espressione +@var{incremento} dell'istruzione @code{for}. Il seguente programma +@`e un esempio di ci@`o: + +@example +BEGIN @{ + for (x = 0; x <= 20; x++) @{ + if (x == 5) + continue + printf "%d ", x + @} + print "" +@} +@end example + +@noindent +Questo programma stampa tutti i numeri da 0 a 20---tranne il 5, in cui +l'istruzione @code{printf} @`e saltata. Siccome l'incremento @samp{x++} +non viene saltato, @code{x} non rimane fermo al valore 5. Si confronti il ciclo +@code{for} dell'esempio precedente con il seguente ciclo @code{while}: + +@example +BEGIN @{ + x = 0 + while (x <= 20) @{ + if (x == 5) + continue + printf "%d ", x + x++ + @} + print "" +@} +@end example + +@noindent +Questo programma inizia un ciclo infinito dopo che @code{x} ha assunto il +valore 5, poich@'e l'istruzione di incremento (@samp{x++}) non @`e mai raggiunta. + +@c @cindex @code{continue}, fuori da un ciclo +@c @cindex funzionalit@`a del passato +@c @cindex linguaggio @command{awk}, versione POSIX +@cindex POSIX @command{awk}, istruzione @code{continue} e +@cindex angolo buio, istruzione @code{continue} +@cindex @command{gawk}, istruzione @code{continue} in +@cindex Brian Kernighan, @command{awk} di +L'istruzione @code{continue} non ha un significato speciale se appare in +un'istruzione @code{switch}, e non ha alcun significato se usata fuori dal +corpo di un ciclo. Le prime versioni di @command{awk} trattavano le +istruzioni @code{continue} che erano fuori da un ciclo allo stesso modo con +cui trattavano l'istruzione @code{break} +fuori da un ciclo: come se fosse un'istruzione @code{next} +@ifset FOR_PRINT +(trattata nella @value{SECTION} seguente). +@end ifset +@ifclear FOR_PRINT +(@pxref{Istruzione next}). +@end ifclear +@value{DARKCORNER} +Versioni recenti di BWK @command{awk} non consentono pi@`u un tale uso, +e lo stesso vale per @command{gawk}. + +@node Istruzione next +@subsection L'istruzione @code{next} +@cindex @code{next}, istruzione +@cindex istruzione @code{next} + +L'istruzione @code{next} fa s@`{@dotless{i}} che @command{awk} termini immediatamente +l'elaborazione del record corrente e proceda a elaborare il record successivo. +Ci@`o vuol dire che nessuna delle eventuali regole successive viene eseguita +per il record corrente e che il resto delle azioni presenti nella +regola correntemente in esecuzione non viene eseguito. + +Si confronti quanto sopra con quel che fa la funzione @code{getline} +(@pxref{Getline}). Anch'essa fa s@`{@dotless{i}} che @command{awk} legga il record +successivo immediatamente, ma non altera il flusso del controllo in alcun +modo (cio@`e, il resto dell'azione in esecuzione prosegue con il nuovo record +in input). + +@cindex @command{awk}, programmi, eseguire +Al livello pi@`u alto, l'esecuzione di un programma @command{awk} @`e un ciclo +che legge un record in input e quindi confronta il criterio di ricerca di +ciascuna regola con il record stesso. Se si vede questo ciclo come un +@code{for} il cui corpo contiene le regole, l'istruzione @code{next} @`e analoga +a un'istruzione @code{continue}. Salta, cio@`e, alla fine del corpo di questo +ciclo implicito +ed esegue l'incremento (ovvero legge un altro record). + +Per esempio, si supponga che un programma @command{awk} agisca solo su record +che hanno quattro campi, e che non dovrebbe terminare con un errore se trova +dei record in input non validi. Per evitare di complicare il resto del +programma, si pu@`o scrivere una regola ``filtro'' a inizio programma, come +mostrato in questo esempio: + +@example +NF != 4 @{ + printf("%s:%d: salto: NF != 4\n", FILENAME, FNR) > "/dev/stderr" + next +@} +@end example + +@noindent +Siccome @`e presente un @code{next}, +le regole successive del programma non elaboreranno i record non validi. +Il messaggio @`e ridiretto al flusso in output +@dfn{standard error}, sul quale vanno scritti i messaggi di errore. +Per maggiori dettagli, si veda +@ref{File speciali}. + +Se l'istruzione @code{next} provoca il raggiungimento della fine del file +in input, vengono eseguite le eventuali regole @code{END} presenti. +@xref{BEGIN/END}. + +L'istruzione @code{next} non @`e consentita all'interno delle regole +@code{BEGINFILE} ed @code{ENDFILE}. +@xref{BEGINFILE/ENDFILE}. + +@c @cindex @command{awk} language, POSIX version +@c @cindex @code{next}, inside a user-defined function +@cindex @code{BEGIN}, criterio di ricerca, istruzioni @code{next}/@code{nextfile} e +@cindex @code{END}, criterio di ricerca, istruzioni @code{next}/@code{nextfile} e +@cindex POSIX @command{awk}, istruzioni @code{next}/@code{nextfile} e +@cindex @code{next}, istruzione, in funzioni definite dall'utente +@cindex funzioni definite dall'utente, istruzioni @code{next}/@code{nextfile} e +Secondo lo standard POSIX, il comportamento di @command{awk} @`e indefinito +se @code{next} @`e usato in una regola @code{BEGIN} o @code{END}. +@command{gawk} considera questo come un errore di sintassi. Sebbene POSIX +non proibisca di usarlo, +molte altre implementazioni di @command{awk} non consentono che l'istruzione +@code{next} sia usata all'interno del corpo di funzioni. +(@pxref{Funzioni definite dall'utente}). +Come tutte le altre istruzioni @code{next}, un'istruzione @code{next} all'interno del +corpo di una funzione legge il record successivo e inizia a elaborarlo +a partire dalla prima regola del programma. + +@node Istruzione nextfile +@subsection L'istruzione @code{nextfile} +@cindex @code{nextfile}, istruzione +@cindex istruzione @code{nextfile} + +L'istruzione @code{nextfile} +@`e simile all'istruzione @code{next}. +Tuttavia, invece di terminare l'elaborazione del record corrente, l'istruzione +@code{nextfile} richiede ad @command{awk} di terminare di elaborare il +@value{DF} corrente. + +Alla fine dell'esecuzione dell'istruzione @code{nextfile}, +@code{FILENAME} @`e +aggiornato per contenere il nome del successivo @value{DF} elencato sulla riga +di comando, @code{FNR} @`e reimpostato a uno, e l'elaborazione riparte con +la prima regola del programma. +Se l'istruzione @code{nextfile} raggiunge la fine dei file in input, +vengono eseguite le eventuali regole @code{END} presenti. +Un'eccezione a questo si ha se @code{nextfile} @`e invocata durante +l'esecuzione di qualche istruzione all'interno di una regola @code{END}; +in questo caso, il programma viene terminato immediatamente. +@xref{BEGIN/END}. + +L'istruzione @code{nextfile} @`e utile quando ci sono parecchi @value{DF} da +elaborare, ma non @`e necessario elaborare ogni record in ogni file. +Senza @code{nextfile}, +per passare al successivo @value{DF}, un programma +dovrebbe continuare a leggere i record che non gli servono. L'istruzione +@code{nextfile} @`e una maniera molto pi@`u efficiente per ottenere lo stesso +risultato. + +In @command{gawk}, l'esecuzione di @code{nextfile} produce ulteriori effetti: +le eventuali regole @code{ENDFILE} +sono eseguite se @command{gawk} non +si trova correntemente all'interno di una regola @code{END} o +@code{BEGINFILE}; @code{ARGIND} @`e +incrementato e le eventuali regole @code{BEGINFILE} sono eseguite. +(@code{ARGIND} non @`e stato ancora trattato. +@xref{Variabili predefinite}.) + +In @command{gawk}, @code{nextfile} @`e utile all'interno di una regola +@code{BEGINFILE} per evitare di elaborare un file che altrimenti causerebbe +un errore fatale in @command{gawk}. +In questo caso, le regole @code{ENDFILE} non vengono eseguite. +@xref{BEGINFILE/ENDFILE}. + +Sebbene possa sembrare che @samp{close(FILENAME)} ottenga lo stesso +risultato di @code{nextfile}, non @`e cos@`{@dotless{i}}. @code{close()} +pu@`o essere usato solo per chiudere file, @dfn{pipe} e coprocessi che siano +stati aperti tramite ridirezioni. Non ha niente a che vedere con +l'elaborazione principale che +@command{awk} fa dei file elencati in @code{ARGV}. + +@quotation NOTA +Per molti anni, @code{nextfile} @`e stata +un'estensione comune. A settembre 2012 si @`e deciso di +includerla nello standard POSIX. +Si veda @uref{http://austingroupbugs.net/view.php?id=607, il sito web dell'Austin Group}. +@end quotation + +@cindex funzioni definite dall'utente, istruzioni @code{next}/@code{nextfile} e +@cindex @code{nextfile}, in funzioni definite dall'utente +@cindex Brian Kernighan, @command{awk} di +@cindex @command{mawk}, programma di utilit@`a +@cindex programma di utilit@`a @command{mawk} +Le versioni correnti di BWK @command{awk} e @command{mawk} +entrambe prevedono @code{nextfile}. Tuttavia, non sono consentite istruzioni +@code{nextfile} all'interno del corpo delle funzioni +(@pxref{Funzioni definite dall'utente}). +@command{gawk} lo permette; una @code{nextfile} all'interno del corpo di una +funzione legge il primo record del file +successivo e inizia l'elaborazione dello stesso +a partire dalla prima regola del programma, esattamente come farebbe +qualsiasi altra istruzione @code{nextfile}. + +@node Istruzione exit +@subsection L'istruzione @code{exit} + +@cindex @code{exit}, istruzione +@cindex istruzione @code{exit} +L'istruzione @code{exit} fa s@`{@dotless{i}} che @command{awk} termini immediatamente +l'esecuzione della regola corrente e che termini di elaborare l'input; +qualsiasi input ancora da elaborare @`e ignorato. L'istruzione @code{exit} @`e +scritta come segue: + +@display +@code{exit} [@var{codice di ritorno}] +@end display + +@cindex @code{BEGIN}, criterio di ricerca, istruzione @code{exit} e +@cindex criterio di ricerca @code{BEGIN}, istruzione @code{exit} e +@cindex @code{END}, criterio di ricerca, istruzione @code{exit} e +@cindex criterio di ricerca @code{END}, istruzione @code{exit} e +Quando un'istruzione @code{exit} @`e eseguita all'interno di una regola @code{BEGIN}, +il programma termina completamente l'elaborazione. Nessun record in input +viene letto. Tuttavia, se una regola @code{END} @`e presente, come parte +dell'esecuzione dell'istruzione @code{exit}, +la regola @code{END} viene eseguita +(@pxref{BEGIN/END}). +Se @code{exit} @`e usata nel corpo di una regola @code{END}, +il programma termina immediatamente. + +Un'istruzione @code{exit} che non fa parte di una regola @code{BEGIN} o @code{END} +termina l'esecuzione di qualsiasi ulteriore regola applicabile al record +corrente, salta la lettura di qualsiasi record in input, ed esegue +le eventuali regole @code{END}. @command{gawk} salta anche le eventuali regole +@code{ENDFILE}, che non vengono eseguite. + +In questo caso, +se non si desidera che la regola @code{END} venga eseguita, si deve impostare +una variabile a un valore diverso da zero, prima di invocare l'istruzione +@code{exit} e controllarne il valore nella regola @code{END}. +@xref{Funzione assert} +per un esempio di questo tipo. + +@cindex angolo buio, istruzione @code{exit} +Se si specifica un argomento all'istruzione @code{exit}, il suo valore @`e +usato come codice di ritorno finale dell'elaborazione @command{awk}. Se non +viene specificato alcun argomento, +@code{exit} fa terminare @command{awk} con un codice di ritorno di +``successo''. +Nel caso in cui un argomento +sia specificato in una prima istruzione @code{exit} e poi @code{exit} sia +chiamato una seconda volta all'interno di una regola @code{END} senza alcun +argomento, @command{awk} usa il valore di ritorno specificato in precedenza. +@value{DARKCORNER} +@xref{Codice di ritorno} per maggiori informazioni. + +@cindex convenzioni di programmazione, istruzione @code{exit} +Per esempio, si supponga che si sia verificata una condizione di errore +difficile o impossibile da gestire. Convenzionalmente, i programmi la +segnalano terminando con un codice di ritorno diverso da zero. Un programma +@command{awk} pu@`o farlo usando un'istruzione @code{exit} con un argomento +diverso da zero, come mostrato nell'esempio seguente: + +@example +BEGIN @{ + if (("date" | getline data_corrente) <= 0) @{ + print "Non riesco a ottenere la data dal sistema" > "/dev/stderr" + exit 1 + @} + print "la data corrente @`e", data_corrente + close("date") +@} +@end example + +@quotation NOTA +Per una completa portabilit@`a, i codici di ritorno dovrebbero essere compresi +tra zero e 126, estremi compresi. +Valori negativi e valori maggiori o uguali a 127, possono non generare +risultati coerenti tra loro in sistemi operativi diversi. +@end quotation + + +@node Variabili predefinite +@section Variabili predefinite +@cindex predefinite, variabili +@cindex variabili predefinite + +La maggior parte delle variabili @command{awk} sono disponibili per essere +usate dall'utente secondo le proprie esigenze; +queste variabili non cambiano mai di valore a meno che il +programma non assegni loro dei valori, e non hanno alcuna influenza sul +programma a meno che non si decida di utilizzarle nel programma. +Tuttavia, alcune variabili in @command{awk} hanno dei significati speciali +predefiniti. +@command{awk} tiene conto di alcune di queste automaticamente, in modo da +rendere possibile la richiesta ad @command{awk} di fare certe cose nella +maniera desiderata. Altre variabili sono impostate automaticamente da +@command{awk}, in modo da poter comunicare al programma in esecuzione +informazioni sul modo di procedere interno di @command{awk}. + +@cindex @command{gawk}, variabili predefinite e +Questa @value{SECTION} documenta tutte le variabili predefinite di +@command{gawk}; molte di queste variabili sono anche documentate nei +@value{CHAPTER} che descrivono le loro aree di influenza. + +@menu +* Variabili modificabili dall'utente:: Variabili predefinite modificabili per + controllare @command{awk}. +* Variabili auto-assegnate:: Variabili predefinite con cui + @command{awk} fornisce informazioni. +* ARGC e ARGV:: Modi di usare @code{ARGC} e @code{ARGV}. +@end menu + +@node Variabili modificabili dall'utente +@subsection Variabili predefinite modificabili per controllare @command{awk} +@cindex variabili predefinite, modificabili dall'utente +@cindex modificabili dall'utente, variabili + +La seguente @`e una lista alfabetica di variabili che @`e possibile modificare per +controllare come @command{awk} gestisce alcuni compiti. + +Le variabili che sono specifiche di @command{gawk} sono contrassegnate da un +cancelletto (@samp{#}). Queste variabili sono estensioni @command{gawk}. +In altre implementazioni di @command{awk}, o se @command{gawk} @`e eseguito in +modalit@`a compatibile +(@pxref{Opzioni}), non hanno un significato speciale. (Eventuali eccezioni +sono menzionate nella descrizione di ogni variabile.) + +@table @code +@cindex @code{BINMODE}, variabile +@cindex variabile @code{BINMODE} +@cindex binario, input/output +@cindex input/output binario +@cindex differenze tra @command{awk} e @command{gawk}, variabile @code{BINMODE} +@item BINMODE # +Su sistemi non-POSIX, questa variabile specifica l'uso della modalit@`a binaria +per tutto l'I/O. I valori numerici di uno, due o tre specificano che i file +in input, i file di output o tutti i file, rispettivamente, devono usare I/O +binario. +Un valore numerico inferiore a zero @`e trattato come zero e un valore +numerico maggiore di tre @`e trattato +come tre. Alternativamente, le stringhe @code{"r"} o @code{"w"} specificano +che i file in input e i file in output, +rispettivamente, devono usare +I/O binario. Una stringa @code{"rw"} o @code{"wr"} indica che tutti i file +devono usare I/O binario. Ogni altro valore di stringa @`e trattato come +@code{"rw"}, ma @command{gawk} genera un messaggio di avvertimento. +@code{BINMODE} @`e descritto in maggior +dettaglio in @ref{Uso su PC}. @command{mawk} (@pxref{Altre versioni}) +prevede questa variabile, ma consente solo valori numerici. + +@cindex @code{CONVFMT}, variabile +@cindex variabile @code{CONVFMT} +@cindex POSIX @command{awk}, variabile @code{CONVFMT} e +@cindex numeri, conversione in stringhe +@cindex stringhe, conversione in numeri +@item @code{CONVFMT} +Una stringa che controlla la conversione di numeri in +stringhe (@pxref{Conversione}). +In effetti @`e la stringa passata come primo argomento alla funzione +@code{sprintf()} +(@pxref{Funzioni per stringhe}). +Il suo valore di default @`e @code{"%.6g"}. +@code{CONVFMT} @`e stata introdotta dallo standard POSIX. + +@cindex @command{gawk}, variabile @code{FIELDWIDTHS} in +@cindex @code{FIELDWIDTHS}, variabile +@cindex variabile @code{FIELDWIDTHS} +@cindex differenze tra @command{awk} e @command{gawk}, variabile @code{FIELDWIDTHS} +@cindex separatori di campo, variabile @code{FIELDWIDTHS} e +@cindex campo, separatori di, variabile @code{FIELDWIDTHS} e +@item FIELDWIDTHS # +Una lista di posizioni di colonna, separate da spazi, per dire a +@command{gawk} +come dividere campi in input posti su colonne fisse. +Assegnando un valore a @code{FIELDWIDTHS}, le variabili @code{FS} e +@code{FPAT} +@emph{non} vengono usate per effettuare la divisione in campi. +@xref{Dimensione costante} per maggiori informazioni. + +@cindex @command{gawk}, variabile @code{FPAT} in +@cindex @code{FPAT}, variabile +@cindex variabile @code{FPAT} +@cindex differenze tra @command{awk} e @command{gawk}, variabile @code{FPAT} +@cindex separatori di campo, variabile @code{FPAT} e +@cindex campo, separatori di, variabile @code{FPAT} e +@item FPAT # +Un'espressione regolare (di tipo stringa) per dire a @command{gawk} +di creare i campi utilizzando come delimitatore il testo che corrisponde +all'espressione regolare. +Assegnando un valore a @code{FPAT} +le variabili @code{FS} e @code{FIELDWIDTHS} +@emph{non} vengono usate per effettuare la divisione in campi. +@xref{Separazione in base al contenuto} per maggiori informazioni. + +@cindex @code{FS}, variabile +@cindex variabile @code{FS} +@cindex campo, separatori di +@cindex separatori di campo +@item FS +Il separatore dei campi in input (@pxref{Separatori di campo}). +Il valore pu@`o essere una stringa di un solo carattere o un'espressione +regolare composta da pi@`u caratteri che individua il separatore tra i campi +dei record in input. Se il suo valore +@`e la stringa nulla (@code{""}), +ogni singolo carattere del record costituisce un campo. +(Questo comportamente @`e un'estensione @command{gawk}. POSIX @command{awk} non +specifica il comportamento quando @code{FS} @`e la stringa nulla. +Nonostante questo, alcune altre versioni di @command{awk} trattano @code{""} +in modo speciale.) + +@cindex POSIX @command{awk}, variabile @code{FS} e +Il valore di default @`e @w{@code{" "}}, una stringa consistente in un singolo +spazio. In via eccezionale, questo valore significa che qualsiasi sequenza +di spazi, TAB, e/o ritorni a capo costituisce +un solo separatore. +Inoltre eventuali spazi, TAB e ritorni a capo all'inizio e alla fine +del record in input vengono ignorati. + +Si pu@`o impostare il valore di @code{FS} sulla riga dei comandi usando +l'opzione @option{-F}: + +@example +awk -F, '@var{programma}' @var{file-in-input} +@end example + +@cindex @command{gawk}, separatori di campo e +Se @command{gawk} sta usando @code{FIELDWIDTHS} o @code{FPAT} +per separare i campi, +assegnare un valore a @code{FS} fa s@`{@dotless{i}} che @command{gawk} torni alla +separazione dei campi normale, fatta utilizzando la variabile @code{FS}. +Un modo semplice per fare questo +@`e semplicemente quello di scrivere l'istruzione +@samp{FS = FS}, aggiungendo magari un commento esplicativo. + +@cindex @command{gawk}, variabile @code{IGNORECASE} in +@cindex @code{IGNORECASE}, variabile +@cindex variabile @code{IGNORECASE} +@cindex differenze tra @command{awk} e @command{gawk}, variabile @code{IGNORECASE} +@cindex maiuscolo/minuscolo e confronti tra stringhe +@cindex maiuscolo/minuscolo e @dfn{regexp} +@cindex espressioni regolari, maiuscolo/minuscolo +@item IGNORECASE # +Se la variabile @code{IGNORECASE} @`e diversa da zero o dalla stringa nulla, +tutti i confronti tra stringhe +e tutti i confronti tra espressioni regolari sono insensibili +alle differenze maiuscolo/minuscolo. +Questo vale per il confronto tra @dfn{regexp} +usando @samp{~} e @samp{!~}, per le funzioni @code{gensub()}, +@code{gsub()}, @code{index()}, @code{match()}, @code{patsplit()}, +@code{split()} e @code{sub()}, +per la determinazione della fine record con @code{RS} e per la divisione +in campi con @code{FS} e @code{FPAT}. +Tuttavia, il valore di @code{IGNORECASE} @emph{non} influenza gli indici +dei vettori +e non influenza la separazione dei campi qualora si usi un separatore di campo +costituito da un unico carattere. +@xref{Maiuscolo-Minuscolo}. + +@cindex @command{gawk}, variabile @code{LINT} in +@cindex @code{LINT}, variabile +@cindex variabile @code{LINT} +@cindex differenze tra @command{awk} e @command{gawk}, variabile @code{LINT} +@cindex @dfn{lint}, controlli +@cindex controlli @dfn{lint} +@item LINT # +Quando questa variabile @`e vera (non uguale a zero e non uguale alla stringa +nulla), @command{gawk} si comporta come se fosse stata specificata sulla +riga di comando l'opzione @option{--lint} +(@pxref{Opzioni}). +Con un valore di @code{"fatal"}, gli avvertimenti di @dfn{lint} generano un errore +fatale. +Con un valore di @code{"invalid"}, sono inviati solo gli avvertimenti +per cose che sono effettivamente non valide. (Questa parte non funziona +ancora perfettamente.) +Ogni altro valore @dfn{vero} stampa avvertimenti non fatali. +Se @code{LINT} ha per valore @dfn{falso} nessun avvertimento @dfn{lint} viene +stampato. + +Questa variabile @`e un'estensione @command{gawk}. Non ha un valore speciale +per altre implementazioni di @command{awk}. A differenza di altre variabili +speciali, modificare il valore di @code{LINT} altera la produzione di +avvertimenti @dfn{lint} anche se @command{gawk} @`e in modalit@`a compatibile. +Analogamente a come le opzioni +@option{--lint} e @option{--traditional} controllano in maniera indipendente +diversi aspetti del comportamente di @command{gawk}, il controllo +degli avvertimenti di @dfn{lint} durante l'esecuzione del programma @`e indipendente +dall'implementazione @command{awk} in esecuzione. + +@cindex @code{OFMT}, variabile +@cindex variabile @code{OFMT} +@cindex numeri, conversione in stringhe +@cindex stringhe, conversione in numeri +@item OFMT +@`E questa la stringa che controlla la conversione di numeri in +stringhe (@pxref{Conversione}) quando li +si stampa con l'istruzione +@code{print}. Funziona passandola + come primo argomento alla funzione @code{sprintf()} +(@pxref{Funzioni per stringhe}). +Il suo valore di default @`e @code{"%.6g"}. Le prime versioni di @command{awk} +usavano @code{OFMT} per specificare il formato da usare per convertire +numeri in stringhe in espressioni generali; questo compito @`e ora svolto +da @code{CONVFMT}. + +@cindex @code{sprintf()}, funzione, variabile @code{OFMT} e +@cindex funzione @code{sprintf()}, variabile @code{OFMT} e +@cindex @code{print}, istruzione, variabile @code{OFMT} e +@cindex istruzione @code{print}, variabile @code{OFMT} e +@cindex variabile @code{OFS} +@cindex @code{OFS}, variabile +@cindex campo, separatori di +@cindex separatori di campo +@item OFS +@`E il separatore dei campi in output (@pxref{Separatori di output}). @`E ci@`o +che viene stampato in output per separare i campi stampati da un'istruzione @code{print}. +Il suo valore di default @`e @w{@code{" "}}, una stringa costituita da un solo +spazio. + +@cindex @code{ORS}, variabile +@cindex variabile @code{ORS} +@item ORS +Il separatore dei record in output. Viene stampato alla fine di ogni +istruzione @code{print}. Il suo valore di default @`e @code{"\n"}, +il carattere di ritorno a capo. +(@xref{Separatori di output}.) + +@cindex @code{PREC}, variabile +@cindex variabile @code{PREC} +@item PREC # +La precisione disponibile nei numeri a virgola mobile a precisione arbitraria, +per default 53 bit (@pxref{Impostare la precisione}). + +@cindex @code{ROUNDMODE}, variabile +@cindex variabile @code{ROUNDMODE} +@item ROUNDMODE # +La modalit@`a di arrotondamento da usare per operazioni aritmetiche a precisione +arbitraria svolte sui numeri, per default @code{"N"} +(@code{roundTiesToEven} nello standard +IEEE 754; @pxref{Impostare modi di arrotondare}). + +@cindex @code{RS}, variabile +@cindex variabile @code{RS} +@cindex separatori di record +@cindex record, separatori di +@item @code{RS} +Il separatore tra record in input. Il suo valore di default @`e una stringa +contenente il solo carattere di ritorno a capo, il che significa che un record in input +consiste di una sola riga di testo. +Il suo valore pu@`o essere anche la stringa nulla, nel qual caso i record sono +separati da una o pi@`u righe vuote. +Se invece @`e una @dfn{regexp}, i record sono separati da +corrispondenze alla @dfn{regexp} nel testo in input. +(@xref{Record}.) + +La possibilit@`a che @code{RS} sia un'espressione regolare +@`e un'estensione @command{gawk}. +In molte altre implementazioni @command{awk}, oppure +se @command{gawk} @`e in modalit@`a compatibile +(@pxref{Opzioni}), +@`e usato solo il primo carattere del valore di @code{RS}. + +@cindex @code{SUBSEP}, variabile +@cindex variabile @code{SUBSEP} +@cindex separatori di indici +@cindex indici, separatori di +@item @code{SUBSEP} +Il separatore di indici. Ha il valore di default di +@code{"\034"} ed @`e usato per separare le parti di cui sono composti gli indici +di un vettore multidimensionale. Quindi, l'espressione +@samp{@w{pippo["A", "B"]}} +in realt@`a accede a @code{pippo["A\034B"]} +(@pxref{Vettori multidimensionali}). + +@cindex @command{gawk}, variabile @code{TEXTDOMAIN} in +@cindex @code{TEXTDOMAIN}, variabile +@cindex variabile @code{TEXTDOMAIN} +@cindex differenze tra @command{awk} e @command{gawk}, variabile @code{TEXTDOMAIN} +@cindex internazionalizzazione, localizzazione +@item TEXTDOMAIN # +Usata per l'internazionalizzazione di programmi a livello di +@command{awk}. Imposta il dominio di testo (@dfn{text domain}) di default per costanti stringa +marcate in maniera speciale nel codice sorgente, e anche per le funzioni +@code{dcgettext()}, @code{dcngettext()} e @code{bindtextdomain()} +@iftex +(@pxrefil{Internazionalizzazione}). +@end iftex +@ifnottex +(@pxref{Internazionalizzazione}). +@end ifnottex +Il valore di default di @code{TEXTDOMAIN} @`e @code{"messages"}. +@end table + +@node Variabili auto-assegnate +@subsection Variabili predefinite con cui @command{awk} fornisce informazioni + +@cindex predefinite, variabili, che forniscono informazioni +@cindex variabili predefinite, che forniscono informazioni +Quella che segue @`e una lista in ordine alfabetico di variabili che +@command{awk} imposta automaticamente in determinate situazioni per +fornire informazioni a un programma. + +Le variabili specifiche di @command{gawk} sono contrassegnate da un +cancelletto (@samp{#}). Queste variabili sono estensioni @command{gawk}. +In altre implementazioni di @command{awk} o se @command{gawk} @`e in +modalit@`a compatibile (@pxref{Opzioni}), non hanno un significato speciale: + +@c @asis for docbook +@table @asis +@cindex @code{ARGC}/@code{ARGV}, variabili +@cindex argomenti, riga di comando +@cindex riga di comando, argomenti +@item @code{ARGC}, @code{ARGV} +Gli argomenti della riga di comando disponibili ai programmi @command{awk} +sono memorizzati in un vettore di nome +@code{ARGV}. @code{ARGC} @`e il numero di argomenti presenti sulla +riga di comando. +@xref{Altri argomenti}. +A differenza di quasi tutti i vettori di @command{awk}, +@code{ARGV} @`e indicizzato da 0 a @code{ARGC} @minus{} 1. +Lo si pu@`o vedere nell'esempio seguente: + +@example +$ @kbd{awk 'BEGIN @{} +> @kbd{for (i = 0; i < ARGC; i++)} +> @kbd{print ARGV[i]} +> @kbd{@}' inventory-shipped mail-list} +@print{} awk +@print{} inventory-shipped +@print{} mail-list +@end example + +@noindent +@code{ARGV[0]} contiene @samp{awk}, @code{ARGV[1]} +contiene @samp{inventory-shipped} e @code{ARGV[2]} contiene +@samp{mail-list}. Il valore di @code{ARGC} @`e tre, ossia uno in pi@`u +dell'indice dell'ultimo elemento di @code{ARGV}, perch@'e gli elementi sono +numerati a partire da zero. + +@cindex convenzioni di programmazione, variabili @code{ARGC}/@code{ARGV} +I nomi @code{ARGC} e @code{ARGV}, come pure la convenzione di indicizzare +il vettore da 0 a @code{ARGC} @minus{} 1, derivano dal modo in cui il +linguaggio C accede agli argomenti presenti sulla riga di comando. + +@cindex angolo buio, valore di @code{ARGV[0]} +Il valore di @code{ARGV[0]} pu@`o variare da sistema a sistema. +Va anche notato che il programma @emph{non} +@`e incluso in @code{ARGV}, e non sono incluse neppure le eventuali opzioni di +@command{awk} specificate sulla riga di comando. +@xref{ARGC e ARGV} per informazioni +su come @command{awk} usa queste variabili. +@value{DARKCORNER} + +@cindex @code{ARGIND}, variabile +@cindex variabile @code{ARGIND} +@cindex differenze tra @command{awk} e @command{gawk}, variabile @code{ARGIND} +@item @code{ARGIND #} +L'indice in @code{ARGV} del file correntemente in elaborazione. +Ogni volta che @command{gawk} apre un nuovo @value{DF} per elaborarlo, imposta +@code{ARGIND} all'indice in @code{ARGV} del @value{FN}. +Quando @command{gawk} sta elaborando i file in input, il confronto +@samp{FILENAME == ARGV[ARGIND]} @`e sempre verificato. + +@cindex file, elaborazione@comma{} variabile @code{ARGIND} e +Questa variabile @`e utile nell'elaborazione dei file; consente di stabilire +a che punto ci si trova nella lista +di @value{DF}, e anche di distinguere tra successive occorrenze dello stesso +@value{FN} sulla riga dei comandi. + +@cindex nomi di file, distinguere +Anche se @`e possibile modificare il valore di @code{ARGIND} all'interno del +programma @command{awk}, @command{gawk} automaticamente lo imposta a un nuovo +valore quando viene aperto il file successivo. + +@cindex @code{ENVIRON}, vettore +@cindex vettore @code{ENVIRON} +@cindex variabili d'ambiente, nel vettore @code{ENVIRON} +@item @code{ENVIRON} +Un vettore associativo contenente i valori delle variabili d'ambiente. +Gli indici del vettore sono i nomi delle variabili d'ambiente; gli elementi +sono i valori della specifica variabile d'ambiente. Per esempio, +@code{ENVIRON["HOME"]} potrebbe valere @code{/home/arnold}. + +Per POSIX @command{awk}, le modifiche a questo vettore non cambiano +le variabili d'ambiente passate a qualsivoglia programma che @command{awk} +pu@`o richiamare tramite una ridirezione +o usando la funzione @code{system()}. + +Tuttavia, a partire dalla @value{PVERSION} 4.2, se non si @`e in +modalit@`a compatibile POSIX, @command{gawk} aggiorna le proprie variabili +d'ambiente, quando si modifica @code{ENVIRON}, e in questo modo sono +modificate anche le variabili d'ambiente disponibili ai programmi richiamati. +Un'attenzione speciale dovrebbe essere prestata alla modifica di +@code{ENVIRON["PATH"]}, che @`e il percorso di ricerca usato per trovare +i programmi eseguibili. + +Queste modifiche possono anche influire sul programma @command{gawk}, poich@'e +alcune funzioni predefinite possono tener conto di certe +variabili d'ambiente. +L'esempio pi@`u notevole di una tale situazione @`e @code{mktime()} +(@pxref{Funzioni di tempo}) +che, in molti sistemi, tiene conto del valore della +variabile d'ambiente @env{TZ}. + +Alcuni sistemi operativi possono non avere variabili d'ambiente. +In tali sistemi, il vettore @code{ENVIRON} @`e vuoto (tranne che per +le variabili +@w{@code{ENVIRON["AWKPATH"]}} e +@w{@code{ENVIRON["AWKLIBPATH"]}} eventualmente presenti; +@pxref{AWKPATH (Variabile)} e +@ifdocbook +@ref{AWKLIBPATH (Variabile)}). +@end ifdocbook +@ifnotdocbook +@pxref{AWKLIBPATH (Variabile)}). +@end ifnotdocbook + +@cindex @command{gawk}, variabile @code{ERRNO} in +@cindex @code{ERRNO}, variabile +@cindex variabile @code{ERRNO} +@cindex differenze tra @command{awk} e @command{gawk}, variabile @code{ERRNO} +@cindex gestione errori, variabile @code{ERRNO} e +@item @code{ERRNO #} +Se si verifica un errore di sistema durante una ridirezione per @code{getline}, +durante una lettura per @code{getline} o durante un'operazione di +@code{close()}, la variabile +@code{ERRNO} contiene una stringa che descrive l'errore. + +Inoltre, @command{gawk} annulla @code{ERRNO} prima di aprire ogni +file in input presente sulla riga di comando. Questo consente di controllare +se il file @`e accessibile +all'interno di un criterio di ricerca @code{BEGINFILE} +(@pxref{BEGINFILE/ENDFILE}). + +Per il resto, @code{ERRNO} si comporta analogamente alla variabile C +@code{errno}. +Tranne nel caso sopra accennato, @command{gawk} non annulla @emph{mai} +@code{ERRNO} (lo imposta a zero o a @code{""}). Quindi, ci si deve +aspettare che il suo valore sia significativo solo quando un'operazione +di I/O restituisce un valore che indica il fallimento dell'operazione, come +per esempio quando @code{getline} restituisce @minus{}1. Si @`e, naturalmente, +liberi di annullarla prima di effettuare un'operazione di I/O. + +Se il valore di @code{ERRNO} corrisponde a un errore di sistema della +variabile C @code{errno}, @code{PROCINFO["errno"]} sar@`a impostato al valore +di @code{errno}. Per errori non di sistema, @code{PROCINFO["errno"]} sar@`a +impostata al valore zero. + +@cindex @code{FILENAME}, variabile +@cindex variabile @code{FILENAME} +@cindex angolo buio, variabile @code{FILENAME} +@item @code{FILENAME} +Il nome del file in input corrente. Quando non ci sono @value{DF} +sulla riga dei comandi, @command{awk} legge dallo standard input e +@code{FILENAME} @`e impostato a @code{"-"}. @code{FILENAME} cambia ogni +volta che si legge un nuovo file +@iftex +(@pxrefil{Leggere file}). +@end iftex +@ifnottex +(@pxref{Leggere file}). +@end ifnottex +All'interno di una +regola @code{BEGIN}, il valore di @code{FILENAME} @`e @code{""}, perch@'e non si +sta elaborando alcun file in input.@footnote{Alcune tra le prime implementazioni di Unix +@command{awk} inizializzavano @code{FILENAME} a @code{"-"}, anche se +vi erano @value{DF} da elaborare. Un tale comportamento era incorretto e +non ci si dovrebbe poter contare nei programmi.} +@value{DARKCORNER} Si noti, tuttavia, +che l'uso di @code{getline} (@pxref{Getline}) all'interno di una regola +@code{BEGIN} pu@`o implicare l'assegnamento di un valore a @code{FILENAME}. + +@cindex @code{FNR}, variabile +@cindex variabile @code{FNR} +@item @code{FNR} +Il numero del record corrente nel file corrente. @command{awk} incrementa +@code{FNR} ogni volta che legge un nuovo record (@pxref{Record}). +@command{awk} imposta nuovamente a zero @code{FNR} ogni volta che inizia a +leggere un nuovo file in input. + +@cindex @code{NF}, variabile +@cindex variabile @code{NF} +@item @code{NF} +Il numero di campi nel corrente record in input. +@code{NF} @`e impostato ogni volta che si legge un nuovo record, +quando un nuovo campo viene creato, +o quando si modifica @code{$0} (@pxref{Campi}). + +A differenza di molte altre variabili descritte in questa @value{SUBSECTION}, +l'assegnamento di un valore a @code{NF} pu@`o potenzialmente influenzare +il funzionamento interno di @command{awk}. In particolare, assegnamenti +a @code{NF} si possono usare per aggiungere o togliere campi dal +record corrente. @xref{Cambiare i campi}. + +@cindex @code{FUNCTAB}, vettore +@cindex vettore @code{FUNCTAB} +@cindex @command{gawk}, vettore @code{FUNCTAB} in +@cindex differenze tra @command{awk} e @command{gawk}, variabile @code{FUNCTAB} +@item @code{FUNCTAB #} +Un vettore i cui indici e i corrispondenti valori sono i nomi di tutte le +funzioni predefinite, definite dall'utente ed estese, presenti nel programma. + +@quotation NOTA +Il tentativo di usare l'istruzione @code{delete} per eliminare il vettore +@code{FUNCTAB} genera un errore fatale. Genera un errore fatale anche +ogni tentativo di impostare un elemento di @code{FUNCTAB}. +@end quotation + +@cindex @code{NR}, variabile +@cindex variabile @code{NR} +@item @code{NR} +Il numero di record in input che @command{awk} ha elaborato dall'inizio +dell'esecuzione del programma +(@pxref{Record}). +@command{awk} incrementa @code{NR} ogni volta che legge un nuovo record. + +@cindex @command{gawk}, vettore @code{PROCINFO} in +@cindex @code{PROCINFO}, vettore +@cindex vettore @code{PROCINFO} +@cindex differenze tra @command{awk} e @command{gawk}, vettore @code{PROCINFO} +@item @code{PROCINFO #} +Gli elementi di questo vettore danno accesso a informazioni sul +programma @command{awk} in esecuzione. +I seguenti elementi (elencati in ordine alfabetico) +sono sicuramente sempre disponibili: + +@table @code +@cindex effettivo, @dfn{ID di gruppo} dell'utente di @command{gawk} +@item PROCINFO["egid"] +Il valore restituito dalla chiamata di sistema @code{getegid()}. + +@item PROCINFO["errno"] +Il valore della variabile C @code{ERRNO} quando @code{ERRNO} @`e impostato +al messaggio di errore a essa associato. + +@item PROCINFO["euid"] +@cindex @dfn{ID effettivo} dell'utente di @command{gawk} +Il valore restituito dalla chiamata di sistema @code{geteuid()}. + +@item PROCINFO["FS"] +Questo elemento vale +@code{"FS"} se @`e in uso la separazione in campi con @code{FS}, +@code{"FIELDWIDTHS"} se @`e in uso quella con @code{FIELDWIDTHS}, +oppure @code{"FPAT"} se @`e in uso l'individuazione di campo con @code{FPAT}. + +@item PROCINFO["gid"] +@cindex @dfn{ID di gruppo} dell'utente @command{gawk} +Il valore restituito dalla chiamata di sistema @code{getgid()} . + +@item PROCINFO["identifiers"] +@cindex programma, identificativi in un +@cindex identificativi in un programma +Un sottovettore, indicizzato dai nomi di tutti gli identificativi usati +all'interno del programma @command{awk}. Un @dfn{identificativo} @`e +semplicemente il nome di una variabile +(scalare o vettoriale), una funzione predefinita, una funzione definita +dall'utente, o una funzione contenuta in un'estensione. +Per ogni identificativo, il valore dell'elemento @`e uno dei seguenti: + +@table @code +@item "array" +L'identificativo @`e un vettore. + +@item "builtin" +L'identificativo @`e una funzione predefinita. + +@item "extension" +L'identificativo @`e una funzione in un'estensione caricata tramite +@code{@@load} o con l'opzione @option{-l}. + +@item "scalar" +L'identificativo @`e uno scalare. + +@item "untyped" +L'identificativo non ha ancora un tipo (potrebbe essere usato come scalare o +come vettore; @command{gawk} non @`e ancora in grado di dirlo). + +@item "user" +L'identificativo @`e una funzione definita dall'utente. +@end table + +@noindent +I valori riportano ci@`o che @command{gawk} sa sugli identificativi +dopo aver finito l'analisi iniziale del programma; questi valori @emph{non} +vengono pi@`u aggiornati durante l'esecuzione del programma. + +@item PROCINFO["pgrpid"] +@cindex @dfn{process group ID} del programma @command{gawk} +Il @dfn{ID di gruppo del processo} del programma corrente. + +@item PROCINFO["pid"] +@cindex @dfn{process ID} del programma @command{gawk} +Il @dfn{process ID} del programma corrente. + +@item PROCINFO["ppid"] +@cindex @dfn{parent process ID} del programma @command{gawk} +Il @dfn{ID di processo del padre} del programma corrente. + +@item PROCINFO["strftime"] +La stringa col formato di default usato per la funzione @code{strftime()}. +Assegnando un nuovo valore a questo elemento si cambia quello di default. +@xref{Funzioni di tempo}. + +@item PROCINFO["uid"] +Il valore restituito dalla chiamata di sistema @code{getuid()}. + +@item PROCINFO["version"] +@cindex versione di @command{gawk} +@cindex @command{gawk}, versione di +La versione di @command{gawk}. +@end table + +I seguenti elementi addizionali del vettore +sono disponibili per fornire informazioni sulle librerie MPFR e GMP, +se la versione in uso di @command{gawk} consente il calcolo con precisione +arbitraria +(@pxref{Calcolo con precisione arbitraria}): + +@table @code +@item PROCINFO["gmp_version"] +@cindex versione della libreria GNU MP +La versione della libreria GNU MP. + +@cindex versione della libreria GNU MPFR +@item PROCINFO["mpfr_version"] +La versione della libreria GNU MPFR. + +@item PROCINFO["prec_max"] +@cindex precisione massima consentita dalla libreria MPFR +La massima precisione consentita da MPFR. + +@item PROCINFO["prec_min"] +@cindex precisione minima richiesta dalla libreria MPFR +La precisione minima richiesta da MPFR. +@end table + +I seguenti elementi addizionali del vettore +sono disponibili per fornire +informazioni sulla versione dell'estensione API, se la versione +di @command{gawk} prevede il caricamento dinamico di funzioni di estensione +@iftex +(@pxrefil{Estensioni dinamiche}): +@end iftex +@ifnottex +(@pxref{Estensioni dinamiche}): +@end ifnottex + +@table @code +@item PROCINFO["api_major"] +@cindex versione dell'estensione API @command{gawk} +@cindex estensione API, numero di versione +La versione principale dell'estensione API. + +@item PROCINFO["api_minor"] +La versione secondaria dell'estensione API. +@end table + +@cindex gruppi supplementari Unix con @command{gawk} +Su alcuni sistemi, ci possono essere elementi nel vettore, da @code{"group1"} +fino a @code{"group@var{N}"}. @var{N} @`e il numero di +gruppi supplementari che il processo [Unix] possiede. Si usi l'operatore +@code{in} per verificare la presenza di questi elementi +(@pxref{Visitare elementi}). + +I seguenti elementi consentono di modificare il comportamento di +@command{gawk}: + +@item PROCINFO["NONFATAL"] +Se questo elemento esiste, gli errori di I/O per tutte le ridirezioni +consentono la prosecuzizone del programma. +@xref{Continuazione dopo errori}. + +@item PROCINFO["@var{nome_output}", "NONFATAL"] +Gli errori in output per il file @var{nome_output} +consentono la prosecuzizone del programma. +@xref{Continuazione dopo errori}. + +@table @code +@item PROCINFO["@var{comando}", "pty"] +Per una comunicazione bidirezionale con @var{comando}, si usi una pseudo-tty +invece di impostare una @dfn{pipe} bidirezionale. +@xref{I/O bidirezionale} per ulteriori informazioni. + +@item PROCINFO["@var{input_name}", "READ_TIMEOUT"] +Imposta un tempo limite per leggere dalla ridirezione di input @var{input_name}. +@xref{Timeout in lettura} per ulteriori informazioni. + +@item PROCINFO["sorted_in"] +Se questo elemento esiste in @code{PROCINFO}, il suo valore controlla +l'ordine in cui gli indici dei vettori saranno elaborati nei cicli +@samp{for (@var{indice} in @var{vettore})}. +Questa @`e una funzionalit@`a avanzata, la cui descrizione completa sar@`a vista +pi@`u avanti; si veda +@ref{Visitare un intero vettore}. +@end table + +@cindex @code{RLENGTH}, variabile +@cindex variabile @code{RLENGTH} +@item @code{RLENGTH} +La lunghezza della sottostringa individuata dalla funzione +@code{match()} +(@pxref{Funzioni per stringhe}). +@code{RLENGTH} viene impostata quando si richiama la funzione @code{match()}. +Il suo +valore @`e la lunghezza della stringa individuata, oppure @minus{}1 se non @`e +stata trovata alcuna corrispondenza. + +@cindex @code{RSTART}, variabile +@cindex variabile @code{RSTART} +@item @code{RSTART} +L'indice, in caratteri, da cui parte la sottostringa che @`e individuata dalla +funzione @code{match()} +(@pxref{Funzioni per stringhe}). +@code{RSTART} viene impostata quando si richiama la funzione @code{match()}. +Il suo +valore @`e la posizione nella stringa da cui inizia la sottostringa +individuata, oppure zero, se non @`e stata trovata alcuna corrispondenza. + +@cindex @command{gawk}, variabile @code{RT} in +@cindex @code{RT}, variabile +@cindex variabile @code{RT} +@cindex differenze tra @command{awk} e @command{gawk}, variabile @code{RT} +@item @code{RT #} +Il testo in input che corrisponde al testo individuato da @code{RS}, +il separatore di record. Questa variabile viene impostata dopo aver letto +ciascun record. + +@cindex @command{gawk}, vettore @code{SYMTAB} in +@cindex @code{SYMTAB}, vettore +@cindex vettore @code{SYMTAB} +@cindex differenze tra @command{awk} e @command{gawk}, vettore @code{SYMTAB} +@item @code{SYMTAB #} +Un vettore i cui indici sono i nomi di tutte le variabili globali e i vettori +definiti nel programma. @code{SYMTAB} rende visibile al +programmatore @command{awk} la tabella dei simboli di @command{gawk}. +Viene preparata nella fase di analisi iniziale del programma @command{gawk} +ed @`e completata prima di cominciare a eseguire il programma. + +Il vettore pu@`o essere usato per accedere indirettamente, in lettura o in +scrittura, al valore di una variabile: + +@example +pippo = 5 +SYMTAB["pippo"] = 4 +print pippo # stampa 4 +@end example + +@noindent +La funzione @code{isarray()} (@pxref{Funzioni per i tipi}) si pu@`o usare per +controllare se un elemento in @code{SYMTAB} @`e un vettore. +Inoltre, non @`e possibile usare l'istruzione @code{delete} con il vettore +@code{SYMTAB}. + +@`E possibile aggiungere a @code{SYMTAB} un elemento che non sia un +identificativo gi@`a esistente: + +@example +SYMTAB["xxx"] = 5 +print SYMTAB["xxx"] +@end example + +@noindent +Il risultato @`e quello previsto: in questo caso @code{SYMTAB} si comporta +come un normale vettore. La sola differenza @`e che non @`e poi possibile +cancellare @code{SYMTAB["xxx"]}. + +@cindex Schorr, Andrew +Il vettore @code{SYMTAB} @`e pi@`u interessante di quel che sembra. Andrew +Schorr fa notare che effettivamente consente di ottenere dei puntatori ai dati +in @command{awk}. Si consideri quest'esempio: + +@example +# Moltiplicazione indiretta di una qualsiasi variabile per un +# numero a piacere e restituzione del risultato + +function multiply(variabile, numero) +@{ + return SYMTAB[variabile] *= numero +@} +@end example + +@noindent +Si potrebbe usare in questo modo: + +@example +BEGIN @{ + risposta = 10.5 + multiply("risposta", 4) + print "La risposta @`e", risposta +@} +@end example + +@noindent +Eseguendo, il risultato @`e: + +@example +$ @kbd{gawk -f risposta.awk} +@print{} La risposta @`e 42 +@end example + +@quotation NOTA +Per evitare seri paradossi temporali, +@footnote{Per non parlare dei grossi problemi di implementazione.} +n@'e @code{FUNCTAB} n@'e @code{SYMTAB} +sono disponibili come elementi all'interno del vettore @code{SYMTAB}. +@end quotation +@end table + +@sidebar Modificare @code{NR} e @code{FNR} +@cindex @code{NR}, variabile, modifica di +@cindex variabile @code{NR}, modifica di +@cindex @code{FNR}, variabile, modifica di +@cindex variabile @code{FNR}, modifica di +@cindex angolo buio, variabili @code{FNR}/@code{NR} +@command{awk} incrementa le variabili @code{NR} e @code{FNR} +ogni volta che legge un record, invece che impostarle al valore assoluto del +numero di record letti. Ci@`o significa che un programma pu@`o +modificare queste variabili e i valori cos@`{@dotless{i}} assegnati sono incrementati per +ogni record. +@value{DARKCORNER} +Si consideri l'esempio seguente: + +@example +$ @kbd{echo '1} +> @kbd{2} +> @kbd{3} +> @kbd{4' | awk 'NR == 2 @{ NR = 17 @}} +> @kbd{@{ print NR @}'} +@print{} 1 +@print{} 17 +@print{} 18 +@print{} 19 +@end example + +@noindent +Prima che @code{FNR} venisse aggiunto al linguaggio @command{awk} +(@pxref{V7/SVR3.1}), +molti programmi @command{awk} usavano questa modalit@`a per +contare il numero di record in un file impostando a zero @code{NR} al cambiare +di @code{FILENAME}. +@end sidebar + +@node ARGC e ARGV +@subsection Usare @code{ARGC} e @code{ARGV} +@cindex @code{ARGC}/@code{ARGV}, variabili, come usarle +@cindex variabili @code{ARGC}/@code{ARGV}, come usarle +@cindex argomenti, riga di comando +@cindex riga di comando, argomenti + +@iftex +La +@end iftex +@ref{Variabili auto-assegnate} +conteneva il programma seguente che visualizzava le informazioni contenute +in @code{ARGC} e @code{ARGV}: + +@example +$ @kbd{awk 'BEGIN @{} +> @kbd{for (i = 0; i < ARGC; i++)} +> @kbd{print ARGV[i]} +> @kbd{@}' inventory-shipped mail-list} +@print{} awk +@print{} inventory-shipped +@print{} mail-list +@end example + +@noindent +In questo esempio, @code{ARGV[0]} contiene @samp{awk}, @code{ARGV[1]} +contiene @samp{inventory-shipped} e @code{ARGV[2]} contiene +@samp{mail-list}. +Si noti che il nome del programma @command{awk} non @`e incluso in @code{ARGV}. +Le altre opzioni della riga di comando, con i relativi argomenti, +sono parimenti non presenti, compresi anche gli assegnamenti di +variabile fatti tramite l'opzione @option{-v} +(@pxref{Opzioni}). +I normali assegnamenti di variabile sulla riga dei comandi @emph{sono} +trattati come argomenti e quindi inseriti nel vettore @code{ARGV}. +Dato il seguente programma in un file di nome @file{vediargomenti.awk}: + +@example +BEGIN @{ + printf "A=%d, B=%d\n", A, B + for (i = 0; i < ARGC; i++) + printf "\tARGV[%d] = %s\n", i, ARGV[i] +@} +END @{ printf "A=%d, B=%d\n", A, B @} +@end example + +@noindent +la sua esecuzione produce il seguente risultato: + +@example +$ @kbd{awk -v A=1 -f vediargomenti.awk B=2 /dev/null} +@print{} A=1, B=0 +@print{} ARGV[0] = awk +@print{} ARGV[1] = B=2 +@print{} ARGV[2] = /dev/null +@print{} A=1, B=2 +@end example + +Un programma pu@`o modificare @code{ARGC} e gli elementi di @code{ARGV}. +Ogni volta che @command{awk} arriva alla fine di un file in input, usa +il successivo elemento nel vettore @code{ARGV} come nome del successivo file +in input. Cambiando il contenuto di quella stringa, un programma +pu@`o +modificare la lista dei file che sono letti. +Si usi @code{"-"} per rappresentare lo standard input. Assegnando ulteriori +elementi e incrementando @code{ARGC} +verranno letti ulteriori file. + +Se il valore di @code{ARGC} viene diminuto, vengono ignorati i file in input +posti alla fine della lista. Memorizzando il valore originale di @code{ARGC} +da qualche altra parte, un programma pu@`o gestire gli argomenti +ignorati come se fossero qualcosa di diverso dai @value{FN}. + +Per eliminare un file che sia in mezzo alla lista, si imposti in @code{ARGV} +la stringa nulla +(@code{""}) al posto del nome del file in questione. Come funzionalit@`a +speciale, @command{awk} ignora valori di @value{FN} che siano stati +rimpiazzati con la stringa nulla. +Un'altra possibilit@`a @`e quella +di usare l'istruzione @code{delete} per +togliere elementi da @code{ARGV} (@pxref{Cancellazione}). + +Tutte queste azioni sono tipicamente eseguite nella regola @code{BEGIN}, +prima di iniziare l'elaborazione vera e propria dell'input. +@xref{Programma split} e +@ifnotdocbook +@pxref{Programma tee} +@end ifnotdocbook +@ifdocbook +@ref{Programma tee} +@end ifdocbook +per esempi +su ognuno dei modi per togliere elementi dal vettore @code{ARGV}. + +Per passare direttamente delle opzioni a un programma scritto in +@command{awk}, si devono terminare le opzioni di @command{awk} con +@option{--} e poi inserire le opzioni destinate al programma @command{awk}, +come mostrato qui di seguito: + +@example +awk -f mio_programma.awk -- -v -q file1 file2 @dots{} +@end example + +Il seguente frammento di programma ispeziona @code{ARGV} per esaminare, e +poi rimuovere, le opzioni sulla riga di comando viste sopra: + +@example +BEGIN @{ + for (i = 1; i < ARGC; i++) @{ + if (ARGV[i] == "-v") + verbose = 1 + else if (ARGV[i] == "-q") + debug = 1 + else if (ARGV[i] ~ /^-./) @{ + e = sprintf("%s: opzione non riconosciuta -- %c", + ARGV[0], substr(ARGV[i], 2, 1)) + print e > "/dev/stderr" + @} else + break + delete ARGV[i] + @} +@} +@end example + +@cindex differenze tra @command{awk} e @command{gawk}, variabili @code{ARGC}/@code{ARGV} +Terminare le opzioni di @command{awk} con @option{--} non @`e +necessario in @command{gawk}. A meno che non si specifichi @option{--posix}, +@command{gawk} inserisce, senza emettere messaggi, ogni opzione non +riconosciuta +nel vettore @code{ARGV} perch@'e sia trattata dal programma @command{awk}. +Dopo aver trovato un'opzione non riconosciuta, @command{gawk} non cerca +ulteriori opzioni, anche se ce ne fossero di riconoscibili. +La riga dei comandi precedente sarebbe +con @command{gawk}: + +@example +gawk -f mio_programma.awk -q -v file1 file2 @dots{} +@end example + +@noindent +Poich@'e @option{-q} non @`e un'opzione valida per @command{gawk}, quest'opzione +e l'opzione @option{-v} che segue sono passate al programma @command{awk}. +(@xref{Funzione getopt} per una funzione di libreria @command{awk} +che analizza le opzioni della riga di comando.) + +Nel progettare un programma, si dovrebbero scegliere opzioni che non +siano in conflitto con quelle di @command{gawk}, perch@'e ogni opzioni +accettata da @command{gawk} verr@`a elaborata prima di passare il resto +della riga dei comandi al programma @command{awk}. +Usare @samp{#!} con l'opzione @option{-E} pu@`o essere utile in questo caso +(@pxref{@dfn{Script} eseguibili} +e +@ifnotdocbook +@pxref{Opzioni}). +@end ifnotdocbook +@ifdocbook +@ref{Opzioni}). +@end ifdocbook + +@node Sommario criteri e azioni +@section Sommario + +@itemize @value{BULLET} +@item +Coppie @dfn{criterio di ricerca--azione} sono gli elementi base di un +programma @command{awk}. I criteri di ricerca possono essere espressioni +normali, espressioni di intervallo, o costanti @dfn{regexp}; possono anche +essere i criteri speciali @code{BEGIN}, @code{END}, +@code{BEGINFILE} o @code{ENDFILE}; o essere omessi. L'azione viene eseguita +se il record corrente soddisfa il criterio di ricerca. Criteri di ricerca +vuoti (omessi) corrispondono a +tutti i record in input. + +@item +L'I/O effettuato nelle azioni delle regole @code{BEGIN} ed @code{END} +ha alcuni vincoli. +Questo vale a maggior ragione per le regole @code{BEGINFILE} ed +@code{ENDFILE}. Queste ultime due forniscono degli ``agganci'' per interagire +con l'elaborazione dei file fatta da @command{gawk}, +consentendo di risolvere situazioni che altrimenti genererebbero degli +errori fatali (ad esempio per un file che non si @`e autorizzati +a leggere). + +@item +Le variabili di shell possono essere usate nei programmi @command{awk} +prestando la dovuta attenzione all'uso degli apici. +@`E pi@`u facile passare una variabile di shell ad +@command{awk} usando l'opzione @option{-v} e una variabile @command{awk}. + +@item +Le azioni sono formate da istruzioni racchiuse tra parentesi graffe. +Le istruzioni sono composte da +espressioni, istruzioni di controllo, +istruzioni composte, +istruzioni di input/output e istruzioni di cancellazione. + +@item +Le istruzioni di controllo in @command{awk} sono @code{if}-@code{else}, +@code{while}, @code{for} e @code{do}-@code{while}. @command{gawk} +aggiunge l'istruzione @code{switch}. Ci sono due tipi di istruzione +@code{for}: uno per eseguire dei cicli, e l'altro per esaminare un vettore. + +@item +Le istruzioni @code{break} e @code{continue} permettono di uscire +velocemente da un ciclo, o di passare alla successiva iterazione dello +stesso (o di uscire da un'istruzione @code{switch}). + +@item +Le istruzioni @code{next} e @code{nextfile} permettono, rispettivamente, +di passare al record successivo, ricominciando l'elaborazione dalla prima +regola del programma, o di passare al successivo file in input, sempre +ripartendo dalla prima regola del programma. + +@item +L'istruzione @code{exit} termina il programma. Quando @`e eseguita +dall'interno di un'azione (o nel corpo di una funzione), trasferisce +il controlla alle eventuali istruzioni @code{END}. Se @`e eseguita nel corpo +di un'istruzione @code{END}, il programma @`e terminato +immediatamente. @`E possibile specificare un valore numerico da usare come +codice di ritorno di @command{awk}. + +@item +Alcune variabili predefinite permettono di controllare @command{awk}, +principalmente per l'I/O. Altre variabili trasmettono informazioni +da @command{awk} al programma. + +@item +I vettori @code{ARGC} e @code{ARGV} rendono disponibili al programma gli +argomenti della riga di comando. Una loro modifica all'interno di una regola +@code{BEGIN} permette di controllare come @command{awk} elaborer@`a i @value{DF} +in input. + +@end itemize + +@node Vettori +@chapter Vettori in @command{awk} +@cindex vettori + +Un @dfn{vettore} @`e una tabella di valori chiamati @dfn{elementi}. Gli +elementi di un vettore sono individuati dai loro @dfn{indici}. Gli indici +possono essere numeri o stringhe. + +Questo @value{CHAPTER} descrive come funzionano i vettori in @command{awk}, +come usare gli elementi di un vettore, come visitare tutti gli elementi +di un vettore, e come rimuovere elementi da un vettore. +Descrive anche come @command{awk} simula vettori multidimensionali, +oltre ad alcuni aspetti meno ovvii sull'uso dei vettori. +Il @value{CHAPTER} prosegue illustrando la funzionalit@`a di ordinamento dei +vettori di @command{gawk}, e termina con una breve descrizione della capacit@`a +di @command{gawk} di consentire veri vettori di vettori. + +@menu +* Fondamenti sui vettori:: Informazioni di base sui vettori. +* Indici numerici di vettore:: Come usare numeri come indici in + @command{awk}. +* Indici non inizializzati:: Usare variabili non inizializzate come indici. +* Cancellazione:: L'istruzione @code{delete} toglie un elemento + da un vettore. +* Vettori multidimensionali:: Emulare vettori multidimensionali in + @command{awk}. +* Vettori di vettori:: Vettori multidimensionali veri. +* Sommario dei vettori:: Sommario dei vettori. +@end menu + +@node Fondamenti sui vettori +@section Informazioni di base sui vettori + +Questa @value{SECTION} espone le nozioni fondamentali: elaborare gli elementi +di un vettore uno alla volta, e visitare sequenzialmente tutti gli elementi +di un vettore. + +@menu +* Introduzione ai vettori:: Introduzione ai vettori +* Visitare elementi:: Come esaminare un elemento di un vettore. +* Impostare elementi:: Come cambiare un elemento di un vettore. +* Esempio di vettore:: Esempio semplice di vettore +* Visitare un intero vettore:: Variazione dell'istruzione @code{for}. Esegue + un ciclo attraverso gli indici degli elementi + contenuti in un vettore. +* Controllare visita:: Controllare l'ordine in cui i vettori sono + visitati. +@end menu + +@node Introduzione ai vettori +@subsection Introduzione ai vettori + +@cindex Wall, Larry +@quotation +@i{Visitare sequenzialmente un vettore associativo @`e come tentare di +lapidare qualcuno usando una mitragliatrice Uzi carica.} +@author Larry Wall +@end quotation + +Il linguaggio @command{awk} mette a disposizione vettori monodimensionali per +memorizzare gruppi di stringhe o di numeri correlati fra loro. Ogni vettore di +@command{awk} deve avere un nome. I nomi dei vettori hanno la stessa sintassi +dei nomi di variabile; qualsiasi nome valido di variabile potrebbe essere anche +un valido nome di vettore. Un nome per@`o non pu@`o essere usato in entrambi i +modi (come vettore e come variabile) nello stesso programma @command{awk}. + +I vettori in @command{awk} assomigliano superficialmente ai vettori in altri +linguaggi di programmazione, ma ci sono differenze fondamentali. In +@command{awk}, non @`e necessario specificare la dimensione di un vettore prima +di iniziare a usarlo. In pi@`u, qualsiasi numero o stringa pu@`o essere usato +come indice di un vettore, non solo numeri interi consecutivi. + +Nella maggior parte degli altri linguaggi, i vettori devono essere +@dfn{dichiarati} prima dell'uso, specificando quanti elementi o componenti +contengono. In questi linguaggi, la dichiarazione causa l'allocazione, per +questi elementi, di un blocco di memoria contiguo. +Normalmente, un indice di un vettore dev'essere un intero non negativo. +Per esempio, l'indice zero specifica il primo elemento nel vettore, che @`e +effettivamente memorizzato all'inizio di un blocco di memoria. L'indice uno +specifica il secondo elemento, che @`e memorizzato subito dopo il primo elemento, +e cos@`{@dotless{i}} via. @`E impossibile aggiungere ulteriori elementi al vettore, perch@'e +esso pu@`o contenere solo il numero di elementi dichiarato. +(Alcuni linguaggi consentono indici iniziali e finali arbitrari---p.es., +@samp{15 .. 27}---per@`o la dimensione del vettore rimane fissa una volta che +il vettore sia stato dichiarato.) + +@c 1/2015: Do not put the numeric values into @code. Array element +@c values are no different than scalar variable values. +Un vettore contiguo di quattro elementi potrebbe essere come quello in +@ifnotdocbook +@ref{vettore-elementi}, +@end ifnotdocbook +@ifdocbook +come mostrato in @inlineraw{docbook, <xref linkend="vettore-elementi"/>}: +@end ifdocbook +concettualmente, se i valori degli elementi sono 8, @code{"pippo"}, +@code{""} e 30. + +@ifnotdocbook +@float Figura,vettore-elementi +@caption{Un vettore contiguo} +@ifset SMALLPRINT +@center @image{vettore-elementi, 11cm, , Un vettore contiguo} +@end ifset +@ifclear SMALLPRINT +@center @image{vettore-elementi, , , Un vettore contiguo} +@end ifclear +@end float +@end ifnotdocbook + +@docbook +<figure id="vettore-elementi" float="0"> +<title>Un vettore contiguo</title> +<mediaobject> +<imageobject role="web"><imagedata fileref="vettore-elementi.png" format="PNG"/></imageobject> +</mediaobject> +</figure> +@end docbook + +@noindent +Vengono memorizzati solo i valori; gli indici sono definiti implicitamente +dall'ordine dei valori. Qui, 8 @`e il valore il cui indice @`e zero, perch@'e 8 +appare nella posizione con zero elementi prima di essa. + +@cindex vettori, indicizzazione +@cindex indicizzare i vettori +@cindex associativi, vettori +@cindex vettori associativi +I vettori in @command{awk} non sono di questo tipo: sono invece +@dfn{associativi}. +Ci@`o significa che ogni vettore @`e un insieme di coppie, ognuna costituita +da un indice e dal corrispondente valore dell'elemento del vettore: + +@ifnotdocbook +@c extra empty column to indent it right +@multitable @columnfractions .1 .1 .1 +@headitem @tab Indice @tab Valore +@item @tab @code{3} @tab @code{30} +@item @tab @code{1} @tab @code{"pippo"} +@item @tab @code{0} @tab @code{8} +@item @tab @code{2} @tab @code{""} +@end multitable +@end ifnotdocbook + +@docbook +<informaltable> +<tgroup cols="2"> +<colspec colname="1" align="left"/> +<colspec colname="2" align="left"/> +<thead> +<row> +<entry>Indice</entry> +<entry>Valore</entry> +</row> +</thead> + +<tbody> +<row> +<entry><literal>3</literal></entry> +<entry><literal>30</literal></entry> +</row> + +<row> +<entry><literal>1</literal></entry> +<entry><literal>"pippo"</literal></entry> +</row> + +<row> +<entry><literal>0</literal></entry> +<entry><literal>8</literal></entry> +</row> + +<row> +<entry><literal>2</literal></entry> +<entry><literal>""</literal></entry> +</row> + +</tbody> +</tgroup> +</informaltable> + +@end docbook + +@noindent +Le coppie sono elencate in ordine casuale perch@'e il loro ordinamento @`e +irrilevante.@footnote{L'ordine potr@`a variare nelle diverse implementazioni +di @command{awk}, che tipicamente usa tabelle @dfn{hash} per memorizzare +elementi e valori del vettore.} + +Un vantaggio dei vettori associativi @`e che si possono aggiungere nuove coppie +in qualsiasi momento. Per esempio, supponiamo di aggiungere al vettore un +decimo elemento il cui valore sia @w{@code{"numero dieci"}}. Il risultato sar@`a: + +@ifnotdocbook +@c extra empty column to indent it right +@multitable @columnfractions .1 .1 .3 +@headitem @tab Indice @tab Valore +@item @tab @code{10} @tab @code{"numero dieci"} +@item @tab @code{3} @tab @code{30} +@item @tab @code{1} @tab @code{"pippo"} +@item @tab @code{0} @tab @code{8} +@item @tab @code{2} @tab @code{""} +@end multitable +@end ifnotdocbook + +@docbook +<informaltable> +<tgroup cols="2"> +<colspec colname="1" align="left"/> +<colspec colname="2" align="left"/> +<thead> +<row> +<entry>Indice</entry> +<entry>Valore</entry> +</row> +</thead> +<tbody> + +<row> +<entry><literal>10</literal></entry> +<entry><literal>"numero dieci"</literal></entry> +</row> + +<row> +<entry><literal>3</literal></entry> +<entry><literal>30</literal></entry> +</row> + +<row> +<entry><literal>1</literal></entry> +<entry><literal>"pippo"</literal></entry> +</row> + +<row> +<entry><literal>0</literal></entry> +<entry><literal>8</literal></entry> +</row> + +<row> +<entry><literal>2</literal></entry> +<entry><literal>""</literal></entry> +</row> + +</tbody> +</tgroup> +</informaltable> + +@end docbook + +@noindent +@cindex sparsi, vettori +@cindex vettori sparsi +Ora il vettore @`e @dfn{sparso}, il che significa semplicemente che non sono +usati alcuni indici. Ha gli elementi 0, 1, 2, 3 e 10, ma mancano gli +elementi 4, 5, 6, 7, 8 e 9. + +Un'altra caratteristica dei vettori associativi @`e che gli indici non devono +essere necessariamente interi non negativi. Qualsiasi numero, o anche una +stringa, pu@`o essere un indice. Per esempio, il seguente @`e un vettore che +traduce delle parole dall'inglese all'italiano: + +@ifnotdocbook +@multitable @columnfractions .1 .1 .1 +@headitem @tab Indice @tab Valore +@item @tab @code{"dog"} @tab @code{"cane"} +@item @tab @code{"cat"} @tab @code{"gatto"} +@item @tab @code{"one"} @tab @code{"uno"} +@item @tab @code{1} @tab @code{"uno"} +@end multitable +@end ifnotdocbook + +@docbook +<informaltable> +<tgroup cols="2"> +<colspec colname="1" align="left"/> +<colspec colname="2" align="left"/> +<thead> +<row> +<entry>Indice</entry> +<entry>Valore</entry> +</row> +</thead> +<tbody> +<row> +<entry><literal>"dog"</literal></entry> +<entry><literal>"cane"</literal></entry> +</row> + +<row> +<entry><literal>"cat"</literal></entry> +<entry><literal>"gatto"</literal></entry> +</row> + +<row> +<entry><literal>"one"</literal></entry> +<entry><literal>"uno"</literal></entry> +</row> + +<row> +<entry><literal>1</literal></entry> +<entry><literal>"uno"</literal></entry> +</row> + +</tbody> +</tgroup> +</informaltable> + +@end docbook + +@noindent +Qui abbiamo deciso di tradurre il numero uno sia nella forma letterale che in +quella numerica, per illustrare che un singolo vettore pu@`o avere come indici +sia numeri che stringhe. +(In effetti, gli indici dei vettori sono sempre stringhe. +Ci sono alcune sottigliezze su come funzionano i numeri quando sono usati come +indici dei vettori; questo verr@`a trattato in maggior dettaglio nella +@ref{Indici numerici di vettore}.) +Qui sopra, il numero @code{1} non @`e tra doppi apici, perch@'e @command{awk} +lo converte automaticamente in una stringa. + +@cindex @command{gawk}, variabile @code{IGNORECASE} in +@cindex maiuscolo/minuscolo, distinzione, indici dei vettori e +@cindex vettori, ordinamento, variabile @code{IGNORECASE} e +@cindex @code{IGNORECASE}, variabile, e indici dei vettori +@cindex variabile @code{IGNORECASE}, e indici dei vettori +Il valore di @code{IGNORECASE} non ha alcun effetto sull'indicizzazione dei +vettori. Lo stesso valore di stringa usato per memorizzare un elemento di un +vettore pu@`o essere usato per richiamarlo. +Quando @command{awk} crea un vettore (p.es., con la funzione predefinita +@code{split()}), gli indici di quel vettore sono numeri interi consecutivi +a partire da uno. +(@xref{Funzioni per stringhe}.) + +I vettori di @command{awk} sono efficienti: il tempo necessario per accedere a +un elemento @`e indipendente dal numero di elementi nel vettore. + +@node Visitare elementi +@subsection Come esaminare un elemento di un vettore +@cindex vettori, esaminare elementi +@cindex vettore, elementi di un +@cindex elementi di un vettore + +Il modo principale di usare un vettore @`e quello di esaminare uno dei suoi +elementi. Un @dfn{riferimento al vettore} @`e un'espressione come questa: + +@example +@var{vettore}[@var{espressione-indice}] +@end example + +@noindent +Qui, @var{vettore} @`e il nome di un vettore. L'espressione +@var{espressione-indice} @`e l'indice dell'elemento del vettore che si vuol +esaminare. + +@c 1/2015: Having the 4.3 in @samp is a little iffy. It's essentially +@c an expression though, so leave be. It's to early in the discussion +@c to mention that it's really a string. +Il valore del riferimento al vettore @`e il valore corrente di quell'elemento +del vettore. Per esempio, @code{pippo[4.3]} @`e un'espressione che richiama +l'elemento del vettore @code{pippo} il cui indice @`e @samp{4.3}. + +@cindex vettori, elementi non assegnati +@cindex elementi di vettore non assegnati +@cindex elementi di vettore vuoti +Un riferimento a un elemento di un vettore il cui indice non esiste ancora +restituisce un valore uguale a @code{""}, la stringa nulla. Questo comprende +elementi a cui non @`e stato assegnato un valore ed elementi che sono stati +eliminati (@pxref{Cancellazione}). + +@cindex elementi inesistenti di un vettore +@cindex vettori, elementi che non esistono +@quotation NOTA +Un riferimento a un elemento inesistente crea @emph{automaticamente} +quell'elemento di vettore, con la stringa nulla come valore. (In certi casi, +ci@`o @`e indesiderabile, perch@'e potrebbe sprecare memoria all'interno di +@command{awk}.) + +I programmatori principianti di @command{awk} fanno spesso l'errore di +verificare se un elemento esiste controllando se il valore @`e vuoto: + +@example +# Verifica se "pippo" esiste in a: @ii{Non corretto!} +if (a["pippo"] != "") @dots{} +@end example + +@noindent +Questo @`e sbagliato per due motivi. Primo, @emph{crea} @code{a["pippo"]} +se ancora non esisteva! Secondo, assegnare a un elemento di un vettore la +stringa vuota come valore @`e un'operazione valida (anche se un po' insolita). +@end quotation + +@c @cindex arrays, @code{in} operator and +@cindex @code{in}, operatore, verificare se un elemento esiste in un vettore +Per determinare se un elemento con un dato indice esiste in un vettore, +si usi la seguente espressione: + +@example +@var{indice} in @var{vettore} +@end example + +@cindex effetti collaterali, indicizzazione di vettori +@noindent +Quest'espressione verifica se lo specifico indice @var{indice} esiste, senza +l'effetto collaterale di creare quell'elemento nel caso che esso non sia +presente. L'espressione ha il valore uno (vero) se +@code{@var{vettore}[@var{indice}]} +esiste e zero (falso) se non esiste. +@c (Qui usiamo @var{indx}, perch@'e @samp{index} @`e il nome di una funzione +@c predefinita.) +Per esempio, quest'istruzione verifica se il vettore @code{frequenze} +contiene l'indice @samp{2}: + +@example +if (2 in frequenze) + print "L'indice 2 @`e presente." +@end example + +Si noti che questo @emph{non} verifica se il vettore +@code{frequenze} contiene un elemento il cui @emph{valore} @`e 2. +Il solo modo far questo @`e quello di passare in rassegna tutti gli +elementi. Inoltre, questo @emph{non} crea @code{frequenze[2]}, mentre la +seguente alternativa (non corretta) lo fa: + +@example +if (frequenze[2] != "") + print "L'indice 2 @`e presente." +@end example + +@node Impostare elementi +@subsection Assegnare un valore a elementi di un vettore +@cindex vettori, elementi, assegnare valori +@cindex elementi di vettori, assegnare valori + +Agli elementi di un vettore possono essere assegnati valori proprio come +alle variabili di @command{awk}: + +@example +@var{vettore}[@var{espressione-indice}] = @var{valore} +@end example + +@noindent +@var{vettore} @`e il nome di un vettore. L'espressione +@var{espressione-indice} @`e l'indice dell'elemento del vettore a cui @`e +assegnato il valore. L'espressione @var{valore} @`e il valore da assegnare +a quell'elemento del vettore. + +@node Esempio di vettore +@subsection Esempio semplice di vettore +@cindex vettori, un esempio sull'uso + +Il seguente programma prende una lista di righe, ognuna delle quali inizia con +un numero di riga, e le stampa in ordine di numero di riga. I numeri di riga +non sono ordinati al momento della lettura, ma sono invece in ordine sparso. +Questo programma ordina le righe mediante la creazione di un vettore che usa +i numeri di riga come indici. Il programma stampa poi le righe +ordinate secondo il loro numero. @`E un programma molto semplice e non @`e in +grado di gestire numeri ripetuti, salti di riga o righe che non +iniziano con un numero: + +@example +@c file eg/misc/arraymax.awk +@{ + if ($1 > massimo) + massimo = $1 + vett[$1] = $0 +@} + +END @{ + for (x = 1; x <= massimo; x++) + print vett[x] +@} +@c endfile +@end example + +La prima regola tiene traccia del numero di riga pi@`u grande visto +durante la lettura; +memorizza anche ogni riga nel vettore @code{vett}, usando come indice +il numero di riga. +La seconda regola viene eseguita dopo che @`e stato letto tutto l'input, per +stampare tutte le righe. +Quando questo programma viene eseguito col seguente input: + +@example +@c file eg/misc/arraymax.data +5 Io sono l'uomo Cinque +2 Chi sei? Il nuovo numero due! +4 . . . E quattro a terra +1 Chi @`e il numero uno? +3 Sei il tre. +@c endfile +@end example + +@noindent +Il suo output @`e: + +@example +1 Chi @`e il numero uno? +2 Chi sei? Il nuovo numero due! +3 Sei il tre. +4 . . . E quattro a terra +5 Io sono l'uomo Cinque +@end example + +Se un numero di riga appare pi@`u di una volta, l'ultima riga con quel dato +numero prevale sulle altre. +Le righe non presenti nel vettore +si possono saltare con un semplice perfezionamento della +regola @code{END} del programma, in questo modo: + +@example +END @{ + for (x = 1; x <= massimo; x++) + if (x in vett) + print vett[x] +@} +@end example + +@node Visitare un intero vettore +@subsection Visitare tutti gli elementi di un vettore +@cindex elementi di vettori, visitare +@cindex visitare vettori +@cindex vettori, visitare +@cindex cicli, @code{for}, visita di un vettore + +Nei programmi che usano vettori, @`e spesso necessario usare un ciclo che +esegue un'azione su ciascun elemento di un vettore. In altri linguaggi, dove +i vettori sono contigui e gli indici sono limitati ai numeri interi +non negativi, +questo @`e facile: tutti gli indici validi possono essere visitati partendo +dall'indice pi@`u basso e arrivando a quello pi@`u alto. Questa tecnica non +@`e applicabile in @command{awk}, perch@'e qualsiasi numero o stringa pu@`o +fare da indice in un vettore. Perci@`o @command{awk} ha un tipo speciale di +istruzione @code{for} per visitare un vettore: + +@example +for (@var{variabile} in @var{vettore}) + @var{corpo} +@end example + +@noindent +@cindex @code{in}, operatore, uso in cicli +@cindex operatore @code{in}, uso in cicli +Questo ciclo esegue @var{corpo} una volta per ogni indice in @var{vettore} che +il programma ha usato precedentemente, con la variabile @var{variabile} +impostata a quell'indice. + +@cindex vettori, istruzione @code{for} e +@cindex @code{for}, istruzione, esecuzione di cicli su un vettore +Il seguente programma usa questa forma dell'istruzione @code{for}. La +prima regola visita i record in input e tiene nota di quali parole appaiono +(almeno una volta) nell'input, memorizzando un 1 nel vettore @code{usate} con +la parola come indice. La seconda regola visita gli elementi di +@code{usate} per trovare tutte le parole distinte che appaiono nell'input. +Il programma stampa poi ogni parola che @`e pi@`u lunga di 10 caratteri e +anche il numero di tali parole. +@xref{Funzioni per stringhe} +per maggiori informazioni sulla funzione predefinita @code{length()}. + +@example +# Registra un 1 per ogni parola usata almeno una volta +@{ + for (i = 1; i <= NF; i++) + usate[$i] = 1 +@} + +# Trova il numero di parole distinte lunghe pi@`u di 10 caratteri +END @{ + for (x in usate) @{ + if (length(x) > 10) @{ + ++numero_parole_lunghe + print x + @} + @} + print numero_parole_lunghe, "parole pi@`u lunghe di 10 caratteri" +@} +@end example + +@noindent +@xref{Programma utilizzo parole} +per un esempio di questo tipo pi@`u dettagliato. + +@cindex vettori, elementi di, ordine di accesso da parte dell'operatore @code{in} +@cindex elementi di vettori, ordine di accesso da parte dell'operatore @code{in} +@cindex @code{in}, operatore, ordine di accesso dei vettori +@cindex operatore @code{in}, ordine di accesso dei vettori +L'ordine nel quale gli elementi del vettore sono esaminati da quest'istruzione +@`e determinato dalla disposizione interna degli elementi del vettore all'interno +di @command{awk} e nell'@command{awk} standard non pu@`o essere controllato +o cambiato. Questo pu@`o portare a dei problemi se vengono aggiunti nuovi +elementi al @var{vettore} dall'istruzione eseguendo il corpo del ciclo; +non @`e prevedibile se il ciclo @code{for} li potr@`a raggiungere. Similmente, +modificare @var{variabile} all'interno del ciclo potrebbe produrre strani +risultati. @`E meglio evitare di farlo. + +Di sicuro, @command{gawk} imposta la lista di elementi su cui eseguire +l'iterazione prima che inizi il ciclo, e non la cambia in corso d'opera. +Ma non tutte le versioni di @command{awk} fanno cos@`{@dotless{i}}. Si consideri questo +programma, chiamato @file{vediciclo.awk}: + +@example +BEGIN @{ + a["questo"] = "questo" + a["@`e"] = "@`e" + a["un"] = "un" + a["ciclo"] = "ciclo" + for (i in a) @{ + j++ + a[j] = j + print i + @} +@} +@end example + +Ecco quel che accade quando viene eseguito con @command{gawk} (e @command{mawk}): + +@example +$ @kbd{gawk -f vediciclo.awk} +@print{} questo +@print{} ciclo +@print{} un +@print{} @`e +@end example + +Se si usa invece BWK @command{awk}: + +@example +$ @kbd{nawk -f vediciclo.awk} +@print{} ciclo +@print{} questo +@print{} @`e +@print{} un +@print{} 1 +@end example + +@node Controllare visita +@subsection Visita di vettori in ordine predefinito con @command{gawk} + +Questa @value{SUBSECTION} descrive una funzionalit@`a disponibile solo in +@command{gawk}. + +Per default, quando un ciclo @code{for} visita un vettore, l'ordine +@`e indeterminato, il che vuol dire che l'implementazione di @command{awk} +determina l'ordine in cui il vettore viene attraversato. +Quest'ordine normalmente @`e basato sull'implementazione interna dei vettori +e varia da una versione di @command{awk} alla successiva. + +@cindex vettori, ordine di visita, controllo dell' +@cindex controllare l'ordine di visita dei vettori +Spesso, tuttavia, servirebbe fare qualcosa di semplice, come +``visitare il vettore confrontando gli indici in ordine crescente,'' +o ``visitare il vettore confrontando i valori in ordine decrescente.'' +@command{gawk} fornisce due meccanismi che permettono di farlo. + +@itemize @value{BULLET} +@item +Assegnare a @code{PROCINFO["sorted_in"]} un valore a scelta fra +alcuni valori predefiniti. +Si vedano pi@`u sotto i valori ammessi. + +@item +Impostare @code{PROCINFO["sorted_in"]} al nome di una funzione definita +dall'utente, da usare per il confronto tra gli elementi di un vettore. Questa +funzionalit@`a avanzata verr@`a descritta in seguito in @ref{Ordinamento di vettori}. +@end itemize + +@cindex @code{PROCINFO}, valori di @code{sorted_in} +Sono disponibili i seguenti valori speciali per @code{PROCINFO["sorted_in"]}: + +@table @code +@item "@@unsorted" +Lasciare gli elementi del vettore in ordine arbitrario +(questo @`e il comportamento di default di @command{awk}). + +@item "@@ind_str_asc" +Ordinare in ordine crescente di indice, confrontando tra loro gli indici +come stringhe; questo @`e l'ordinamento pi@`u normale. +(Internamente, gli indici dei vettori sono sempre stringhe, per cui con +@samp{a[2*5] = 1} l'indice @`e la stringa @code{"10"} e non il numero 10.) + +@item "@@ind_num_asc" +Ordinare in ordine crescente di indice, ma nell'elaborazione gli indici vengono +trattati come numeri. Gli indici con valore non numerico verranno posizionati +come se fossero uguali a zero. + +@item "@@val_type_asc" +Ordinare secondo il valore degli elementi in ordine crescente (invece che in +base agli indici). L'ordinamento @`e in base al tipo assegnato all'elemento +(@pxref{Tipi di variabile e confronti}). +Tutti i valori numerici precedono tutti i valori di tipo stringa, +che a loro volta vengono prima dei sottovettori. +(I sottovettori non sono ancora stati descritti; +@pxref{Vettori di vettori}.) + +@item "@@val_str_asc" +Ordinare secondo il valore degli elementi in ordine crescente (invece che in +base agli indici). I valori scalari sono confrontati come stringhe. +I sottovettori, se presenti, vengono per ultimi. + +@item "@@val_num_asc" +Ordinare secondo il valore degli elementi in ordine crescente (invece che in +base agli indici). I valori scalari sono confrontati come numeri. +I sottovettori, se presenti, vengono per ultimi. +Quando i valori numerici coincidono, vengono usati i valori di tipo stringa +per stabilire un ordinamento: ci@`o garantisce risultati coerenti tra differenti +versioni della funzione C @code{qsort()},@footnote{Quando due elementi +risultano uguali, la funzione C @code{qsort()} non garantisce +che dopo l'ordinamento venga rispettato il loro ordine relativo originale. +Usando il valore di stringa per stabilire un ordinamento univoco quando i +valori numerici sono uguali assicura che il comportamento di @command{gawk} +sia coerente in differenti ambienti.} che @command{gawk} usa internamente +per effettuare l'ordinamento. + +@item "@@ind_str_desc" +Ordinare come fa @code{"@@ind_str_asc"}, ma gli +indici di tipo stringa sono ordinati dal pi@`u alto al pi@`u basso. + +@item "@@ind_num_desc" +Ordinare come fa @code{"@@ind_num_asc"}, ma gli +indici numerici sono ordinati dal pi@`u alto al pi@`u basso. + +@item "@@val_type_desc" +Ordinare come fa @code{"@@val_type_asc"}, ma i valori +degli elementi, a seconda del tipo, sono ordinati dal pi@`u alto al pi@`u basso. +I sottovettori, se presenti, vengono per primi. + +@item "@@val_str_desc" +Ordinare come fa @code{"@@val_str_asc"}, ma i valori degli +elementi, trattati come stringhe, sono ordinati dal pi@`u alto al pi@`u basso. +I sottovettori, se presenti, vengono per primi. + +@item "@@val_num_desc" +Ordinare come fa @code{"@@val_num_asc"}, ma i valori degli +elementi, trattati come numeri, sono ordinati dal pi@`u alto al pi@`u basso. +I sottovettori, se presenti, vengono per primi. +@end table + +L'ordine in cui il vettore @`e visitato viene determinato prima di iniziare +l'esecuzione del ciclo @code{for}. Cambiare @code{PROCINFO["sorted_in"]} +all'interno del corpo del ciclo non influisce sul ciclo stesso. +Per esempio: + +@example +$ @kbd{gawk '} +> @kbd{BEGIN @{} +> @kbd{ a[4] = 4} +> @kbd{ a[3] = 3} +> @kbd{ for (i in a)} +> @kbd{ print i, a[i]} +> @kbd{@}'} +@print{} 4 4 +@print{} 3 3 +$ @kbd{gawk '} +> @kbd{BEGIN @{} +> @kbd{ PROCINFO["sorted_in"] = "@@ind_str_asc"} +> @kbd{ a[4] = 4} +> @kbd{ a[3] = 3} +> @kbd{ for (i in a)} +> @kbd{ print i, a[i]} +> @kbd{@}'} +@print{} 3 3 +@print{} 4 4 +@end example + +Quando si ordina un vettore in base al valore dei suoi elementi, se viene +trovato un valore che @`e un sottovettore, questo @`e considerato pi@`u grande di +qualsiasi stringa o valore numerico, indipendentemente da quel che contiene +lo stesso sottovettore, e tutti i sottovettori sono trattati come se fossero +l'uno uguale all'altro. Il loro ordine reciproco @`e determinato dai loro +indici, visti come stringhe. + +Di seguito sono elencati alcuni punti da tener presenti sulla visita +ordinata dei vettori: + +@itemize @value{BULLET} +@item +Il valore di @code{PROCINFO["sorted_in"]} @`e globale. Cio@`e, ha effetto su tutti +i cicli @code{for} relativi a qualsiasi vettore. Se si deve cambiarlo +all'interno del proprio codice, si dovrebbe vedere se era gi@`a stato +definito in precedenza, e salvare il valore relativo, per ripristinarlo +successivamente: + +@example +@dots{} +if ("sorted_in" in PROCINFO) @{ + ordine_salvato = PROCINFO["sorted_in"] + PROCINFO["sorted_in"] = "@@val_str_desc" # o qualcos'altro +@} +@dots{} +if (ordine_salvato) + PROCINFO["sorted_in"] = ordine_salvato +@end example + +@item +Come gi@`a accennato, l'ordine di visita di default del vettore +@`e rappresentato da @code{"@@unsorted"}. Si pu@`o ottenere il comportamento di +default anche assegnando la stringa nulla a @code{PROCINFO["sorted_in"]} o +semplicemente eliminando l'elemento @code{"sorted_in"} dal vettore +@code{PROCINFO} con l'istruzione @code{delete}. +(L'istruzione @code{delete} non @`e stata ancora descritta; @pxref{Cancellazione}.) +@end itemize + +Inoltre, @command{gawk} fornisce funzioni predefinite per l'ordinamento +dei vettori; si veda @ref{Funzioni di ordinamento di vettori}. + +@node Indici numerici di vettore +@section Usare numeri per indicizzare i vettori + +@cindex numeri, come indici di vettore +@cindex vettori, indici numerici di +@cindex indici di vettori, numeri come +@cindex @code{CONVFMT}, variabile, e indici di vettore +Un aspetto importante da ricordare riguardo ai vettori @`e che +@emph{gli indici dei vettori sono sempre stringhe}. +Quando un valore numerico @`e usato come indice, +viene convertito in un valore di tipo stringa prima di essere usato per +l'indicizzazione (@pxref{Conversione}). +Ci@`o vuol dire che il valore della variabile predefinita @code{CONVFMT} pu@`o +influire su come un programma ha accesso agli elementi di un vettore. +Per esempio: + +@example +xyz = 12.153 +dati[xyz] = 1 +CONVFMT = "%2.2f" +if (xyz in dati) + printf "%s @`e in dati\n", xyz +else + printf "%s non @`e in dati\n", xyz +@end example + +@noindent +Il risultato @`e @samp{12.15 non @`e in dati}. La prima istruzione d@`a a +@code{xyz} un valore numerico. L'assegnamento a @code{dati[xyz]} +indicizza @code{dati} col valore di tipo stringa @code{"12.153"} +(usando il valore di conversione di default @code{CONVFMT}, @code{"%.6g"}). +Quindi, all'elemento del vettore @code{dati["12.153"]} @`e assegnato il valore +uno. Il programma cambia poi +il valore di @code{CONVFMT}. La verifica @samp{(xyz in dati)} genera un nuovo +valore di stringa da @code{xyz}---questa volta @code{"12.15"}---perch@'e il +valore di @code{CONVFMT} consente solo due cifre decimali. Questa +verifica d@`a esito negativo, perch@'e @code{"12.15"} @`e diverso da @code{"12.153"}. + +@cindex convertire numeri interi che sono indici di vettore +@cindex numeri interi, indici di vettore +Secondo le regole di conversione +(@pxref{Conversione}), i valori numerici interi +vengono convertiti in stringhe sempre come interi, indipendentemente dal +valore che potrebbe avere @code{CONVFMT}. E infatti il caso +seguente produce il risultato atteso: + +@example +for (i = 1; i <= maxsub; i++) + @ii{fa qualcosa con} vettore[i] +@end example + +La regola ``i valori numerici interi si convertono sempre in stringhe intere'' +ha un'altra conseguenza per l'indicizzazione dei vettori. +Le costanti ottali ed esadecimali +@ifnotdocbook +(@pxref{Numeri non-decimali}) +@end ifnotdocbook +@ifdocbook +(trattate in @ref{Numeri non-decimali}) +@end ifdocbook +vengono convertite internamente in numeri, e la loro forma originale +non viene pi@`u ricordata. Ci@`o significa, per esempio, che +@code{vettore[17]}, +@code{vettore[021]} e +@code{vettore[0x11]} fanno riferimento tutti allo stesso +elemento! + +Come molte cose in @command{awk}, molto spesso le cose +funzionano come ci si aspetta. @`E utile comunque avere una +conoscenza precisa delle regole applicate, poich@'e a volte possono avere +effetti difficili da individuare sui programmi. + +@node Indici non inizializzati +@section Usare variabili non inizializzate come indici + +@cindex variabili non inizializzate, come indici di vettore +@cindex non inizializzate, variabili, come indici di vettore +@cindex indici di vettore, variabili non inizializzate come +@cindex vettori, indici, variabili non inizializzate come +Supponiamo che sia necessario scrivere un programma +per stampare i dati di input in ordine inverso. +Un tentativo ragionevole per far ci@`o (con qualche dato di +prova) potrebbe essere qualcosa di questo tipo: + +@example +$ @kbd{echo 'riga 1} +> @kbd{riga 2} +> @kbd{riga 3' | awk '@{ l[righe] = $0; ++righe @}} +> @kbd{END @{} +> @kbd{for (i = righe - 1; i >= 0; i--)} +> @kbd{print l[i]} +> @kbd{@}'} +@print{} riga 3 +@print{} riga 2 +@end example + +Sfortunatamente, la prima riga di dati in input non appare +nell'output! + +A prima vista, verrebbe da dire che questo programma avrebbe dovuto +funzionare. La variabile @code{righe} +non @`e inizializzata, e le variabili non inizializzate hanno il valore numerico +zero. Cos@`{@dotless{i}}, @command{awk} dovrebbe aver stampato il valore @code{l[0]}. + +Qui il problema @`e che gli indici per i vettori di @command{awk} sono +@emph{sempre} stringhe. Le variabili non inizializzate, quando sono usate come +stringhe, hanno il valore @code{""}, e non zero. Quindi, @samp{riga 1} +finisce per essere memorizzata in @code{l[""]}. +La seguente variante del programma funziona correttamente: + +@example +@{ l[righe++] = $0 @} +END @{ + for (i = righe - 1; i >= 0; i--) + print l[i] +@} +@end example + +Qui, @samp{++} forza @code{righe} a essere di tipo numerico, rendendo +quindi il ``vecchio valore'' uno zero numerico. Questo viene poi convertito +in @code{"0"} come l'indice del vettore. + +@cindex nulle, stringhe, come indici di vettore +@cindex stringhe nulle, come indici di vettore +@cindex angolo buio, indici di vettori +@cindex @dfn{lint}, controlli, indici di vettori +@cindex controlli @dfn{lint}, indici di vettori +Anche se la cosa pu@`o sembrare strana, la stringa nulla +(@code{""}) @`e un indice di vettore valido. +@value{DARKCORNER} +Se viene fornita l'opzione @option{--lint} sulla riga di comando +@pxref{Opzioni}), @command{gawk} avvisa quando la stringa nulla viene usata +come indice. + +@node Cancellazione +@section L'istruzione @code{delete} +@cindex @code{delete}, istruzione +@cindex istruzione @code{delete} +@cindex eliminare elementi di vettori +@cindex vettori, elementi, eliminazione di +@cindex elementi di vettori, eliminazione di + +Per rimuovere un singolo elemento da un vettore si usa l'istruzione +@code{delete}: + +@example +delete @var{vettore}[@var{espressione-indice}] +@end example + +Una volta che un elemento di un vettore @`e stato eliminato, il valore che aveva +quell'elemento non @`e pi@`u disponibile. @`E come se quell'elemento non sia +mai stato referenziato oppure come se non gli sia mai stato assegnato un +valore. Il seguente @`e un esempio di eliminazione di elementi da un vettore: + +@example +for (i in frequenze) + delete frequenze[i] +@end example + +@noindent +Quest'esempio rimuove tutti gli elementi dal vettore @code{frequenze}. Una +volta che un elemento @`e stato eliminato, una successiva istruzione @code{for} +che visiti il vettore non trover@`a quell'elemento, e l'uso dell'operatore +@code{in} per controllare la presenza di quell'elemento restituisce zero (cio@`e +falso): + +@example +delete pippo[4] +if (4 in pippo) + print "Questo non verr@`a mai stampato" +@end example + +@cindex nulle, stringhe, ed eliminazione di elementi di un vettore +@cindex stringhe nulle, ed eliminazione di elementi di un vettore +@`E importante notare che eliminare un elemento @emph{non} @`e la stessa cosa +che assegnargli un valore nullo (la stringa vuota, @code{""}). +Per esempio: + +@example +pippo[4] = "" +if (4 in pippo) + print "Questo viene stampato, anche se pippo[4] @`e vuoto" +@end example + +@cindex @dfn{lint}, controlli, elementi di vettori +@cindex controlli @dfn{lint}, elementi di vettori +@cindex elementi di vettori, controlli @dfn{lint} per +Non @`e un errore eliminare un elemento che non esiste. +Tuttavia, se viene data l'opzione @option{--lint} sulla riga di comando +(@pxref{Opzioni}), +@command{gawk} emette un messaggio di avvertimento quando viene eliminato un +elemento che non @`e presente in un vettore. + +@cindex comuni, estensioni, @code{delete} per eliminare interi vettori +@cindex estensioni comuni@comma{} @code{delete} per eliminare interi vettori +@cindex vettori, eliminare l'intero contenuto +@cindex eliminare interi vettori +@cindex @code{delete}, @var{vettore} +@cindex differenze tra @command{awk} e @command{gawk}, elementi dei vettori, eliminazione +Tutti gli elementi di un vettore possono essere eliminati con una singola +istruzione omettendo l'indice nell'istruzione @code{delete}, +in questo modo: + + +@example +delete @var{vettore} +@end example + +L'uso di questa versione dell'istruzione @code{delete} @`e circa tre volte pi@`u +efficiente dell'equivalente ciclo che elimina gli elementi uno +alla volta. + +Questa forma dell'istruzione @code{delete} @`e ammessa anche +da BWK @command{awk} e da @command{mawk}, e anche da +diverse altre implementazioni. + +@cindex Brian Kernighan, @command{awk} di +@quotation NOTA +Per molti anni, l'uso di @code{delete} senza un indice era un'estensione +comune. A settembre 2012 si @`e deciso di includerla nello +standard POSIX. Si veda @uref{http://austingroupbugs.net/view.php?id=544, +il sito dell'Austin Group}. +@end quotation + +@cindex portabilit@`a, eliminazione di elementi di un vettore +@cindex Brennan, Michael +La seguente istruzione fornisce un modo portabile, anche se non evidente, +per svuotare un vettore:@footnote{Un ringraziamento a Michael +Brennan per la segnalazione.} + +@example +split("", vettore) +@end example + +@cindex @code{split()}, funzione, eliminazione di elementi di vettori +@cindex funzione @code{split()}, eliminazione di elementi di vettori +La funzione @code{split()} +(@pxref{Funzioni per stringhe}) +dapprima svuota il vettore indicato. La chiamata chiede di dividere +la stringa nulla. Poich@'e non c'@`e nulla da dividere, la +funzione si limita a svuotare il vettore e poi termina. + +@quotation ATTENZIONE +L'eliminazione di tutti gli elementi di un vettore non cambia il suo tipo; non +si pu@`o svuotare un vettore e poi usare il nome del vettore come scalare +(cio@`e, come una variabile semplice). Per esempio, questo non @`e consentito: + +@example +a[1] = 3 +delete a +a = 3 +@end example +@end quotation + +@node Vettori multidimensionali +@section Vettori multidimensionali + +@menu +* Visitare vettori multidimensionali:: Visitare vettori multidimensionali. +@end menu + +@cindex indici di vettori multidimensionali +@cindex vettori multidimensionali +@cindex multidimensionali, vettori +Un @dfn{vettore multidimensionale} @`e un vettore in cui un elemento @`e +identificato da un insieme di indici invece che da un indice singolo. Per +esempio, un vettore bidimenisonale richiede due indici. Il modo consueto (in +molti linguaggi, compreso @command{awk}) per far riferimento a un elemento di +un vettore multidimensionale chiamato @code{griglia} @`e con +@code{griglia[@var{x},@var{y}]}. + +@cindex @code{SUBSEP}, variabile, e vettori multidimensionali +@cindex variabile @code{SUBSEP}, e vettori multidimensionali +I vettori multidimensionali sono resi disponibili in @command{awk} attraverso +la concatenazione di pi@`u indici in una stringa; +@command{awk} converte gli indici in stringhe +(@pxref{Conversione}) e +le concatena assieme, inserendo un separatore tra ognuna di loro. Ne +risulta una sola stringa che include i valori di ogni indice. La +stringa cos@`{@dotless{i}} composta viene usata come un singolo indice in un vettore +ordinario monodimensionale. Il separatore usato @`e il valore della variabile +predefinita @code{SUBSEP}. + +Per esempio, supponiamo di valutare l'espressione @samp{pippo[5,12] = "valore"} +quando il valore di @code{SUBSEP} @`e @code{"@@"}. I numeri 5 e 12 vengono +convertiti in stringhe che sono poi +concatenate con un @samp{@@} tra di essi, dando @code{"5@@12"}; di conseguenza, +l'elemento del vettore @code{pippo["5@@12"]} @`e impostato a @code{"valore"}. + +Una volta che il valore dell'elemento @`e memorizzato, @command{awk} +ignora se sia stato memorizzato con un solo indice o con una +serie di indici. Le due espressioni @samp{pippo[5,12]} e +@w{@samp{pippo[5 SUBSEP 12]}} sono sempre equivalenti. + +Il valore di default di @code{SUBSEP} @`e la stringa @code{"\034"}, +che contiene un carattere non stampabile che difficilmente appare in +un programma di @command{awk} e nella maggior parte dei dati di input. +Il vantaggio di scegliere un carattere improbabile discende dal fatto che i +valori degli indici che contengono una stringa corrispondente a @code{SUBSEP} +possono portare a stringhe risultanti ambigue. Supponendo che +@code{SUBSEP} valga @code{"@@"}, @w{@samp{pippo["a@@b", "c"]}} e +@w{@samp{pippo["a", "b@@c"]}} risultano indistinguibili perch@'e entrambi +sarebbero in realt@`a memorizzati come @samp{pippo["a@@b@@c"]}. + +@cindex @code{in}, operatore, verificare se un elemento esiste in un vettore multidimensionale +Per verificare se una determinata sequenza di indici esiste in un vettore +multidimensionale, si usa lo stesso operatore (@code{in}) che viene usato +per i vettori monodimensionali. Si scrive l'intera sequenza di indici tra +parentesi, separati da virgole, come operando di sinistra: + +@example +if ((@var{indice1}, @var{indice2}, @dots{}) in @var{vettore}) + @dots{} +@end example + +Qui vediamo un esempio, avendo in input un vettore bidimensionale +di campi, ruota questo vettore di 90 gradi in senso orario e stampa il +risultato. Si suppone che tutte le righe in input contengano lo stesso +numero di elementi: + +@example +@{ + if (max_nf < NF) + max_nf = NF + max_nr = NR + for (x = 1; x <= NF; x++) + vettore[x, NR] = $x +@} + +END @{ + for (x = 1; x <= max_nf; x++) @{ + for (y = max_nr; y >= 1; --y) + printf("%s ", vettore[x, y]) + printf("\n") + @} +@} +@end example + +@noindent +Dato l'input: + +@example +1 2 3 4 5 6 +2 3 4 5 6 1 +3 4 5 6 1 2 +4 5 6 1 2 3 +@end example + +@noindent +il programma produce il seguente output: + +@example +4 3 2 1 +5 4 3 2 +6 5 4 3 +1 6 5 4 +2 1 6 5 +3 2 1 6 +@end example + +@node Visitare vettori multidimensionali +@subsection Visitare vettori multidimensionali + +Non c'@`e un'istruzione @code{for} particolare per visitare un +vettore ``multidimensionale''. Non ce ne pu@`o essere una, perch@'e +@command{awk} in realt@`a non ha +vettori o elementi multidimensionali: c'@`e solo una modalit@`a +multidimensionale per @emph{accedere} a un vettore. + +@cindex indici di vettori multidimensionali, visitare gli +@cindex vettori, multidimensionali, visitare +@cindex visitare vettori multidimensionali +Comunque, se un programma ha un vettore al quale si accede sempre in +modalit@`a multidimensionale, si pu@`o ottenere il risultato di visitarlo +combinando l'istruzione di visita @code{for} +(@pxref{Visitare un intero vettore}) con la funzione +interna @code{split()} +(@pxref{Funzioni per stringhe}). +Si procede nel seguente modo: + +@example +for (indice_combinato in vettore) @{ + split(indice_combinato, indici_separati, SUBSEP) + @dots{} +@} +@end example + +@noindent +Questo imposta la variabile @code{indice_combinato} a ogni +concatenazione di indici contenuta nel vettore, e la suddivide +nei singoli indici separandoli +in corrispondenza del valore di +@code{SUBSEP}. I singoli indici diventano poi gli elementi +del vettore @code{indici_separati}. + +Perci@`o, se un valore @`e stato precedentemente memorizzato in +@code{vettore[1, "pippo"]}, esiste in @code{vettore} un elemento con indice +@code{"1\034pippo"} (ricordare che il valore di default di @code{SUBSEP} +@`e il carattere con codice ottale 034). +Prima o poi, l'istruzione @code{for} trova quell'indice e fa un'iterazione +con la variabile @code{indice_combinato} impostata a @code{"1\034pippo"}. +Poi viene chiamata la funzione @code{split()} in questo modo: + +@example +split("1\034pippo", indici_separati, "\034") +@end example + +@noindent +Il risultato @`e quello di impostare @code{indici_separati[1]} a @code{"1"} e +@code{indici_separati[2]} a @code{"pippo"}. Ecco fatto! +La sequenza originale degli indici separati @`e ripristinata. + + +@node Vettori di vettori +@section Vettori di vettori +@cindex vettori di vettori + +@command{gawk} migliora l'accesso ai vettori multidimensionali di +@command{awk} standard e mette a disposizione dei veri vettori di vettori. +Agli elementi di un sottovettore si fa riferimento tramite il loro indice +racchiuso tra parentesi quadre, proprio come gli elementi del vettore +principale. Per esempio, quel che segue crea un sottovettore con due elementi +all'indice @code{1} del vettore principale @code{a}: + +@example +a[1][1] = 1 +a[1][2] = 2 +@end example + +Questo simula un vero vettore bidimensionale. Ogni elemento di un sottovettore +pu@`o contenere un altro sottovettore come valore, che a sua volta pu@`o +contenere anche ulteriori vettori. In questo modo, si possono creare vettori +di tre o pi@`u dimensioni. +Gli indici possono essere costituiti da qualunque espressione di +@command{awk}, compresi dei +valori scalari separati da virgole (cio@`e, un indice multidimensionale simulato +di @command{awk}). Quindi, la seguente espressione @`e valida in +@command{gawk}: + +@example +a[1][3][1, "nome"] = "barney" +@end example + +Ogni sottovettore e il vettore principale possono essere di diversa lunghezza. +Di fatto, gli elementi di un vettore o un suo sottovettore non devono essere +necessariamente tutti dello stesso tipo. Ci@`o significa che il vettore +principale come anche uno qualsiasi dei suoi sottovettori pu@`o essere +non rettangolare, +o avere una struttura frastagliata. Si pu@`o assegnare un valore scalare +all'indice @code{4} del vettore principale @code{a}, anche se @code{a[1]} +@`e esso stesso un vettore e non uno scalare: + +@example +a[4] = "Un elemento in un vettore frastagliato" +@end example + +I termini @dfn{dimensione}, @dfn{riga} e @dfn{colonna} sono privi di +significato quando sono applicati +a questo tipo di vettore, ma d'ora in poi useremo ``dimensione'' per indicare +il numero massimo di indici necessario per far riferimento a un elemento +esistente. Il tipo di ogni elemento che @`e gi@`a stato assegnato non pu@`o essere +cambiato assegnando un valore di tipo diverso. Prima si deve eliminare +l'elemento corrente, per togliere completamente dalla memoria di +@command{gawk} ogni riferimento a quell'indice: + +@example +delete a[4] +a[4][5][6][7] = "Un elemento in un vettore quadridimensionale" +@end example + +@noindent +Le due istruzioni rimuovono il valore scalare dall'indice @code{4} e +inseriscono poi un +sottovettore interno a tre indici contenente uno scalare. Si pu@`o anche +eliminare un intero sottovettore o un sottovettore di sottovettori: + +@example +delete a[4][5] +a[4][5] = "Un elemento nel sottovettore a[4]" +@end example + +Si deve per@`o ricordare che non @`e consentito eliminare il vettore principale +@code{a} e poi usarlo come scalare. + +Le funzioni predefinite che accettano come argomenti dei vettori possono +essere usate +anche con i sottovettori. Per esempio, il seguente frammento di codice usa +@code{length()} (@pxref{Funzioni per stringhe}) +per determinare il numero di elementi nel vettore principale @code{a} +e nei suoi sottovettori: + +@example +print length(a), length(a[1]), length(a[1][3]) +@end example + +@noindent +Il risultato per il nostro vettore principale @code{a} @`e il seguente: + +@example +2, 3, 1 +@end example + +@noindent +L'espressione @samp{@var{indice} in @var{vettore}} +(@pxref{Visitare elementi}) funziona allo stesso modo sia per +i vettori regolari in stile @command{awk} +che per i vettori di vettori. Per esempio, le espressioni @samp{1 in a}, +@samp{3 in a[1]} e @samp{(1, "nome") in a[1][3]} risultano tutte di valore +uno (vero) per il nostro vettore @code{a}. + +L'istruzione @samp{for (elemento in vettore)} (@pxref{Visitare un intero vettore}) +pu@`o essere nidificata per visitare tutti gli +elementi di un vettore di vettori che abbia una struttura rettangolare. Per +stampare il contenuto (valori scalari) di un vettore di vettori bidimensionale +(cio@`e nel quale ogni elemento di primo livello @`e esso stesso un +vettore, non necessariamente di lunghezza uguale agli altri) +si pu@`o usare il seguente codice: + +@example +for (i in vettore) + for (j in vettore[i]) + print vettore[i][j] +@end example + +La funzione @code{isarray()} (@pxref{Funzioni per i tipi}) +permette di verificare se un elemento di un vettore @`e esso stesso un vettore: + +@example +for (i in vettore) @{ + if (isarray(vettore[i]) @{ + for (j in vettore[i]) @{ + print vettore[i][j] + @} + @} + else + print vettore[i] +@} +@end example + +Se la struttura di un vettore di vettori frastagliato @`e nota in anticipo, +si pu@`o spesso trovare il modo per visitarlo usando istruzioni di controllo. +Per esempio, +il seguente codice stampa gli elementi del nostro vettore principale @code{a}: + +@example +for (i in a) @{ + for (j in a[i]) @{ + if (j == 3) @{ + for (k in a[i][j]) + print a[i][j][k] + @} else + print a[i][j] + @} +@} +@end example + +@noindent +@xref{Visitare vettori} per una funzione definita dall'utente che +``visita'' un vettore di vettori di dimensioni arbitrarie. + +Si ricordi che un riferimento a un elemento di un vettore non +inizializzato genera un elemento con valore uguale a @code{""}, la stringa +nulla. Questo ha +un'importante implicazione quando s'intende usare un sottovettore come +argomento di una funzione, come illustrato nel seguente esempio: + +@example +$ @kbd{gawk 'BEGIN @{ split("a b c d", b[1]); print b[1][1] @}'} +@error{} gawk: riga com.:1: fatale: split: secondo argomento +@error{} non-vettoriale +@end example + +Il modo per aggirare quest'ostacolo @`e quello di definire prima @code{b[1]} +come vettore creando un indice arbitrario: + +@example +$ @kbd{gawk 'BEGIN @{ b[1][1] = ""; split("a b c d", b[1]); print b[1][1] @}'} +@print{} a +@end example + +@node Sommario dei vettori +@section Sommario + +@itemize @value{BULLET} +@item +@command{awk} standard dispone di vettori associativi monodimensionali +(vettori indicizzati da valori di tipo stringa). Tutti i vettori sono +associativi; gli indici numerici vengono convertiti automaticamente in +stringhe. + +@item +Agli elementi dei vettori si fa riferimento come +@code{@var{vettore}[@var{indice}]}. Fare riferimento a un elemento lo +crea se questo non esiste ancora. + +@item +Il modo corretto per vedere se un vettore ha un elemento con un dato indice +@`e quello di usare l'operatore @code{in}: @samp{@var{indice} in @var{vettore}}. + +@item +Si usa @samp{for (@var{indice} in @var{vettore}) @dots{}} per visitare +ogni singolo elemento di un vettore. Nel corpo del ciclo, +@var{indice} assume via via il valore dell'indice di ogni elemento del vettore. + +@item +L'ordine in cui il ciclo @samp{for (@var{indice} in @var{vettore})} +attraversa un vettore non @`e definito in POSIX @command{awk} e varia a seconda +dell'implementazione. @command{gawk} consente di controllare l'ordinamento +di visita +assegnando speciali valori predefiniti a @code{PROCINFO["sorted_in"]}. + +@item +Si usa @samp{delete @var{vettore}[@var{indice}]} per eliminare un singolo +elemento di un vettore. +Per eliminare tutti gli elementi di un vettore, +si usa @samp{delete @var{vettore}}. +Quest'ultima funzionalit@`a @`e stata per molti anni un'estensione comune +e ora @`e standard, ma potrebbe non essere disponibile in tutte le +versioni commerciali di @command{awk}. + +@item +@command{awk} standard simula vettori multidimensionali ammettendo pi@`u indici +separati da virgole. I loro valori sono concatenati in un'unica +stringa, separati dal valore di @code{SUBSEP}. Il modo di creazione +dell'indice non viene immagazzinato; cos@`{@dotless{i}}, +cambiare @code{SUBSEP} potrebbe avere conseguenze inaspettate. Si pu@`o usare +@samp{(@var{sub1}, @var{sub2}, @dots{}) in @var{vettore}} per vedere se +un certo indice multidimensionale esiste in @var{vettore}. + +@item +@command{gawk} consente di avere a disposizione veri vettori di vettori. +Si usa una coppia +di parentesi quadre per ogni dimensione in tali vettori: +@code{dati[riga][colonna]}, per esempio. Gli elementi del vettore possono +poi essere valori scalari (numeri o stringhe) o altri vettori. + +@item +Si usa la funzione predefinita @code{isarray()} per determinare se un elemento +di un vettore @`e esso stesso un sottovettore. + +@end itemize + +@node Funzioni +@chapter Funzioni + +@cindex funzioni predefinite +@cindex predefinite, funzioni +Questo @value{CHAPTER} descrive le funzioni predefinite di @command{awk}, +che sono di tre tipi: numeriche, di stringa, e di I/O. +@command{gawk} mette a disposizione ulteriori tipi di funzioni +per gestire valori che rappresentano marcature temporali, per manipolare bit, per +ordinare vettori, per fornire informazioni sui tipi di variabile, +per internazionalizzare e localizzare i programmi.@footnote{Per +un'introduzione alle tematiche suddette, si pu@`o consultare l'articolo +"Localizzazione dei programmi" nel +@uref{http://www.pluto.it/files/journal/pj0404/l10n.html, sito pluto.it.}} + +Oltre alle funzioni predefinite, @command{awk} consente di +scrivere nuove funzioni utilizzabili all'interno di un programma. +La seconda met@`a di questo @value{CHAPTER} descrive le funzioni +@dfn{definite dall'utente}. +Vengono infine descritte le chiamate indirette a una funzione, un'estensione +specifica di @command{gawk} che consente di stabilire durante l'esecuzione del +programma quale funzione chiamare. + +@menu +* Funzioni predefinite:: Riepilogo delle funzioni predefinite. +* Funzioni definite dall'utente:: Descrizione dettagliata delle funzioni + definite dall'utente. +* Chiamate indirette:: Scegliere la funzione da chiamare in + fase di esecuzione del programma. +* Sommario delle funzioni:: Sommario delle funzioni. +@end menu + +@node Funzioni predefinite +@section Funzioni predefinite + +Le funzioni @dfn{predefinite} sono sempre disponibili per essere chiamate +da un programma @command{awk}. Questa @value{SECTION} definisce tutte le +funzioni predefinite di @command{awk}; di alcune di queste si fa menzione +in altre @value{SECTIONS}, +ma sono comunque riassunte anche qui per comodit@`a. + +@menu +* Chiamare funzioni predefinite:: Come chiamare funzioni predefinite. +* Funzioni numeriche:: Funzioni che trattano numeri, comprese + @code{int()}, @code{sin()} e @code{rand()}. +* Funzioni per stringhe:: Funzioni di manipolazione di stringhe, + come @code{split()}, @code{match()} + e @code{sprintf()}. +* Funzioni di I/O:: Funzioni per i file e per i comandi + della shell. +* Funzioni di tempo:: Funzione per gestire marcature temporali. +* Funzioni a livello di bit:: Funzioni per operazioni di + manipolazione bit. +* Funzioni per i tipi:: Funzioni per informazioni sul tipo + di una variabile. +* Funzioni di internazionalizzazione:: Funzioni per tradurre stringhe. +@end menu + +@node Chiamare funzioni predefinite +@subsection Chiamare funzioni predefinite + +Per chiamare una delle funzioni predefinite di @command{awk}, +si scrive il nome della funzione seguito dai suoi argomenti racchiusi +tra parentesi. Per esempio, @samp{atan2(y + z, 1)} +@`e una chiamata alla funzione @code{atan2()} e ha due argomenti. + +@cindex convenzioni di programmazione, nelle chiamate di funzione +@cindex spazio bianco, nelle chiamate di funzione +La presenza di spazi bianchi tra il nome della funzione predefinita +e la parentesi aperta @`e consentita, ma @`e buona norma quella di evitare +di inserire spazi bianchi in quella posizione. +Le funzioni definite dall'utente non consentono che vi siano spazi bianchi +fra nome funzione e aperta parentesi, +ed @`e pi@`u semplice evitare errori seguendo una semplice convenzione che +resta sempre valida: non inserire spazi dopo il nome di una funzione. + +@cindex risoluzione di problemi, @command{gawk}, errori fatali@comma{} argomenti di funzione e +@cindex problemi, risoluzione di, @command{gawk}, errori fatali@comma{} argomenti di funzione e +@cindex @command{gawk}, argomenti di funzione e +@cindex differenze tra @command{awk} e @command{gawk}, argomenti di funzione (@command{gawk}) +Ogni funzione predefinita accetta un certo numero di argomenti. +In alcuni casi, gli argomenti possono essere omessi. I valori di default per +gli argomenti omessi variano +da funzione a funzione e sono descritti insieme a +ciascuna funzione. In alcune implementazioni di @command{awk}, gli +eventuali argomenti in pi@`u specificati per le funzioni predefinite sono +ignorati. Tuttavia, in @command{gawk}, +@`e un errore fatale fornire argomenti in pi@`u a una funzione predefinita. + +Quando si richiama una funzione viene calcolato, prima di effettuare la +chiamata, il valore assunto dalle espressioni che descrivono i parametri +da passare alla funzione. +Per esempio, nel seguente frammento di codice: + +@example +i = 4 +j = sqrt(i++) +@end example + +@cindex ordine di valutazione, funzioni +@cindex funzioni predefinite, ordine di valutazione +@cindex predefinite, funzioni, ordine di valutazione +@noindent +la variabile @code{i} @`e incrementata al valore cinque prima di chiamare +la funzione @code{sqrt()} alla quale viene fornito come parametro il valore +quattro. +L'ordine di valutazione delle espressioni usate come parametri per la +funzione @`e indefinito. Per questo motivo, si deve evitare di scrivere +programmi che presuppongono che i parametri siano valutati da sinistra a +destra o da destra a sinistra. Per esempio: + +@example +i = 5 +j = atan2(++i, i *= 2) +@end example + +Se l'ordine di valutazione @`e da sinistra a destra, @code{i} assume dapprima +il valore 6, e quindi il valore 12, e la funzione @code{atan2()} @`e chiamata +con i due argomenti 6 e 12. Ma se l'ordine di valutazione @`e da destra a +sinistra, @code{i} assume dapprima il valore 10, e poi il valore 11, e la +funzione @code{atan2()} @`e chiamata con i due argomenti 11 e 10. + +@node Funzioni numeriche +@subsection Funzioni numeriche +@cindex funzioni numeriche +@cindex numeriche, funzioni + +La seguente lista descrive tutte le +funzioni predefinite che hanno a che fare con i numeri. +I parametri facoltativi sono racchiusi tra parentesi quadre@w{ ([ ]):} + +@c @asis for docbook +@table @asis +@item @code{atan2(@var{y}, @var{x})} +@cindexawkfunc{atan2} +@cindex arcotangente +Restituisce l'arcotangente di @code{@var{y} / @var{x}} in radianti. +Si pu@`o usare @samp{pi = atan2(0, -1)} per ottenere il valore di +@value{PI} greco. + +@item @code{cos(@var{x})} +@cindexawkfunc{cos} +@cindex coseno +Restituisce il coseno di @var{x}, con @var{x} in radianti. + +@item @code{exp(@var{x})} +@cindexawkfunc{exp} +@cindex esponenziale +Restituisce l'esponenziale di @var{x} (@code{e ^ @var{x}}) o un messaggio +di errore se @var{x} @`e fuori dall'intervallo consentito. +L'intervallo entro il quale pu@`o variare @var{x} +dipende dalla rappresentazione dei numeri in virgola mobile nella macchina in +uso. + +@item @code{int(@var{x})} +@cindexawkfunc{int} +@cindex arrotondamento all'intero pi@`u vicino +Restituisce l'intero pi@`u vicino a @var{x}, situato tra @var{x} e zero, +troncato togliendo i decimali. +Per esempio, @code{int(3)} @`e 3, @code{int(3.9)} @`e 3, @code{int(-3.9)} +@`e @minus{}3, e @code{int(-3)} @`e ancora @minus{}3. + +@item @code{intdiv(@var{numeratore}, @var{denominatore}, @var{risultato})} +@cindexawkfunc{intdiv} +@cindex funzione @code{intdiv} +Esegue una divisione tra numeri interi, simile alla funzione standard C +che ha lo stesso nome. Dapprima, il @code{numeratore} e il +@code{denominatore} vengono troncati, eliminando la parte decimale, +per trasformarli in numeri interi. +Il vettore @code{risultato} viene dapprima svuotato, e poi viene impostato +l'elemento @code{risultato["quotient"]} al risultato della divisione +@samp{numeratore / denominatore}, troncato a numero intero +mediante l'eliminazione dei decimali, +e viene impostato l'elemento @code{risultato["remainder"]} al +risultato dell'operazione @samp{numeratore % denominatore}, troncato a +numero intero allo stesso modo del risultato. Questa funzione @`e +rivolta principalmente a chi usa numeri interi di lunghezza arbitraria; +consente di evitare la creazione di numeri in virgola mobile +di precisione arbitaria usando la funzionalit@`a MPFR +(@pxref{Interi a precisione arbitraria}). + +Questa funzione @`e un'estensione @code{gawk}. Non @`e disponibile in +modalit@`a compatibile (@pxref{Opzioni}). + +@item @code{log(@var{x})} +@cindexawkfunc{log} +@cindex logaritmo +Restituisce il logaritmo naturale di @var{x}, se @var{x} @`e positivo; +altrimenti, restituisce @code{NaN} (``not a number'') sui sistemi che +implementano lo standard IEEE 754. +Inoltre, @command{gawk} stampa un messaggio di avvertimento qualora @code{x} +sia negativo. + +@item @code{rand()} +@cindexawkfunc{rand} +@cindex numeri casuali, funzioni @code{rand()}/@code{srand()} +Restituisce un numero casuale. I valori di @code{rand()} sono +uniformemente distribuiti tra zero e uno. +Il valore potrebbe essere zero ma non @`e mai uno.@footnote{La versione C di +@code{rand()} in molti sistemi Unix +produce notoriamente delle sequenze piuttosto mediocri di numeri casuali. +Tuttavia, non @`e prescritto che un'implementazione di @command{awk} +debba usare la funzione @code{rand()} del linguaggio C per implementare +la versione @command{awk} di @code{rand()}. +In effetti, @command{gawk} usa, per generare numeri casuali, +la funzione @code{random()} di BSD, che @`e +notevolmente migliore di @code{rand()}} + +Spesso servono dei numeri casuali interi invece che frazionari. +La seguente funzione definita dall'utente pu@`o essere usata per ottenere +un numero casuale non negativo inferiore a @var{n}: + +@example +function randint(n) +@{ + return int(n * rand()) +@} +@end example + +@noindent +La moltiplicazione produce un numero casuale maggiore o uguale a zero e +minore di @code{n}. Tramite @code{int()}, questo risultato diventa +un intero tra zero e @code{n} @minus{} 1, estremi inclusi. + +Il seguente esempio usa una funzione simile per generate interi casuali +fra uno e @var{n}. Il programma stampa un numero casuale per +ogni record in input: + +@example +# funzione per simulare un tiro di dado. +function roll(n) @{ return 1 + int(rand() * n) @} + +# Tira 3 dadi a sei facce e +# stampa il numero di punti. +@{ + printf("%d punteggio\n", roll(6) + roll(6) + roll(6)) +@} +@end example + +@cindex inizializzazione generazione di numeri casuali +@cindex numeri casuali, inizializzazione generazione di +@cindex numeri casuali, seme di +@quotation ATTENZIONE +Nella maggior parte delle implementazioni di @command{awk}, compreso +@command{gawk}, +@code{rand()} inizia a generare numeri casuali partendo sempre +dallo stesso numero, o @dfn{seme}, per ogni invocazione di +@command{awk}.@footnote{@command{mawk} +usa un seme differente ogni volta.} @`E per questo motivo che +un programma genera sempre gli stessi risultati ogni volta che lo si esegue. +I numeri sono casuali all'interno di una singola esecuzione di @command{awk} +ma "prevedibili" in ogni successiva esecuzione. +Ci@`o torna utile in fase di test, ma se si desidera che +un programma generi sequenze differenti di numeri casuali ogni volta +che @`e chiamato, occorre impostare il seme a un valore che cambi +per ogni esecuzione. Per fare questo, @`e prevista la funzione @code{srand()}. +@end quotation + +@item @code{sin(@var{x})} +@cindexawkfunc{sin} +@cindex seno +Restituisce il seno di @var{x}, con @var{x} espresso in radianti. + +@item @code{sqrt(@var{x})} +@cindexawkfunc{sqrt} +@cindex radice quadrata +Restituisce la radice quadrata positiva di @var{x}. +@command{gawk} stampa un messaggio di avvertimento +se @var{x} @`e un numero negativo. Quindi, @code{sqrt(4)} vale 2. + +@item @code{srand(}[@var{x}]@code{)} +@cindexawkfunc{srand} +Imposta al valore @var{x} il numero di partenza, o seme, +utilizzato per generare numeri casuali. + +Ogni seme genera una sequenza particolare di numeri casuali.@footnote{I +numeri casuali generati da un computer non sono veramente casuali. +Tecnicamente sono conosciuti come numeri @dfn{pseudo-casuali}. Ci@`o vuol dire +che, anche se i numeri in una sequenza sembrano casuali, @`e possibile +in realt@`a generare la stessa sequenza di numeri casuali pi@`u e pi@`u volte.} +Quindi, impostando il seme allo stesso valore una seconda volta, +viene prodotta ancora la stessa sequenza di numeri casuali. + +@quotation ATTENZIONE +Differenti implementazioni di @command{awk} usano internamente differenti +generatori di numeri casuali. Non si deve dare per scontato che lo stesso +programma @command{awk} +generi la stessa serie di numeri casuali se viene eseguito da differenti +versioni di @command{awk}. +@end quotation + +Se si omette l'argomento @var{x}, scrivendo @samp{srand()}, viene usato +come seme la data e ora corrente. @`E questo il modo per ottenere numeri +casuali che sono veramente imprevedibili. + +Il valore restituito da @code{srand()} @`e quello del seme precedente. +Questo per facilitare il monitoraggio dei semi, nel caso occorra riprodurre +in maniera coerente delle sequenze di numeri casuali. + +POSIX non specifica quale debba essere il seme iniziale, che quindi varia +a seconda delle implementazioni @command{awk}. +@end table + +@node Funzioni per stringhe +@subsection Funzioni di manipolazione di stringhe +@cindex funzioni di manipolazione di stringhe + +Le funzioni in questa @value{SECTION} leggono o modificano il testo di +una o pi@`u stringhe. + +@command{gawk} implementa la localizzazione +(@pxref{Localizzazioni}) ed effettua +ogni manipolazione di stringhe trattando ogni singolo @emph{carattere}, non +ogni singolo @emph{byte}. +Questa distinzione @`e particolarmente importante da comprendere per +quelle localizzazioni in cui un singolo carattere pu@`o essere rappresentato +da pi@`u di un byte. +Quindi, per esempio, la funzione @code{length()} restituisce il numero di +caratteri in una stringa, e non il numero di byte usato per rappresentare quei +caratteri. Allo stesso modo, @code{index()} restituisce indici di caratteri, e +non indici di byte. + +@quotation ATTENZIONE +Un certo numero di funzioni riguarda indici all'interno di stringhe. Per +queste funzioni, il primo carattere di una stringa @`e alla posizione +(all'indice) uno. Questo comportamento @`e differente da quello del C e dei +linguaggi che da esso discendono, nei quali il primo carattere @`e alla posizione +zero. @`E importante ricordarlo quando si fanno calcoli sugli indici, in +particolare se si ha familiarit@`a con il linguaggio C. +@end quotation + +Nella lista seguente, i parametri facoltativi sono racchiusi tra parentesi +quadre@w{ ([ ]).} +Parecchie funzioni operano sostituzioni in una stringa; la spiegazione +completa di ci@`o @`e contenuta nella descrizione della funzione @code{sub()}, +che si trova quasi alla fine di questa lista, ordinata alfabeticamente. + +Le funzioni specifiche di @command{gawk} sono contrassegnate col simbolo +del cancelletto (@samp{#}). Tali funzioni non sono disponibili in modalit@`a +compatibile (@pxref{Opzioni}): + + +@menu +* Dettagli ostici:: Pi@`u di quel che si vorrebbe sapere su @samp{\} + e @samp{&} con @code{sub()}, @code{gsub()}, e + @code{gensub()}. +@end menu + +@c @asis for docbook +@table @asis +@item @code{asort(}@var{sorgente} [@code{,} @var{destinazione} [@code{,} @var{come} ] ]@code{) #} +@itemx @code{asorti(}@var{sorgente} [@code{,} @var{destinazione} [@code{,} @var{come} ] ]@code{) #} +@cindexgawkfunc{asorti} +@cindex vettori, ordinamento dei +@cindex ordinamento di vettori +@cindex vettori, determinare il numero degli elementi +@cindexgawkfunc{asort} +@cindex ordinamento vettori per indici +@cindex vettori, ordinamento per indici +@cindex indici di vettori, ordinamento per +Queste due funzioni sono abbastanza simili, e quindi sono descritte +insieme. + +@quotation NOTA +La seguente descrizione ignora il terzo argomento, @var{come}, perch@'e +richiede la conoscenza di funzionalit@`a di cui non si @`e ancora parlato. Per +questo motivo la seguente trattazione @`e volutamente semplificata. (In seguito +l'argomento verr@`a trattato in maniera pi@`u esauriente; si veda @ref{Funzioni di +ordinamento di vettori} per la descrizione completa.) +@end quotation + +Entrambe le funzioni restituiscono il numero di elementi nel vettore @var{sorgente}. +Con @command{asort()}, @command{gawk} ordina i valori di @var{sorgente} +e rimpiazza gli indici dei valori ordinati di @var{sorgente} con +numeri interi sequenziali, a partire da uno. Se si specifica il vettore +opzionale @var{destinazione}, +@var{sorgente} @`e copiato in @var{destinazione}. @var{destinazione} +viene quindi ordinato, lasciando immodificati gli indici di @var{sorgente}. + +@cindex @command{gawk}, variabile @code{IGNORECASE} in +Nel confronto tra stringhe, la variabile @code{IGNORECASE} influenza +l'ordinamento +(@pxref{Funzioni di ordinamento di vettori}). Se il vettore +@var{sorgente} contiene sottovettori come valori +(@pxref{Vettori di vettori}), questi saranno alla fine, dopo tutti i valori +scalari. +I sottovettori @emph{non} vengono ordinati ricorsivamente. + +Per esempio, se i contenuti del vettore @code{a} sono i seguenti: + +@example +a["ultimo"] = "de" +a["primo"] = "sac" +a["mediano"] = "cul" +@end example + +@noindent +Una chiamata a @code{asort()}: + +@example +asort(a) +@end example + +@noindent +genera i seguenti contenuti di @code{a}: + +@example +a[1] = "cul" +a[2] = "de" +a[3] = "sac" +@end example + +La funzione @code{asorti()} si comporta in maniera simile ad @code{asort()}; +tuttavia l'ordinamento avviene in base agli @emph{indici}, e non in base ai +valori. Quindi, nell'esempio seguente, a partire dallo stesso insieme iniziale +di indici e valori nel vettore @code{a}, la chiamata di @samp{asorti(a)} +produrrebbe: + +@example +a[1] = "mediano" +a[2] = "primo" +a[3] = "ultimo" +@end example + +@item @code{gensub(@var{regexp}, @var{rimpiazzo}, @var{come}} [@code{, @var{obiettivo}}]@code{) #} +@cindexgawkfunc{gensub} +@cindex cercare e rimpiazzare in stringhe +@cindex sostituzione in stringa +Ricerca nella stringa @var{obiettivo} delle corrispondenze +all'espressione regolare @var{regexp}. +Se @var{come} @`e una stringa che inizia +con @samp{g} o @samp{G} (abbreviazione di ``global''), sostituisce +ogni occorrenza di @var{regexp} con la stringa +@var{rimpiazzo}. Altrimenti, @var{come} @`e visto come un numero che indica +quale corrispondenza di @var{regexp} va rimpiazzata. Se non si specifica +il nome dell'@var{obiettivo}, si +opera su @code{$0}. La funzione restituisce come risultato la stringa +modificata, e la stringa originale di partenza @emph{non} viene modificata. + +@code{gensub()} @`e una funzione generale di sostituzione. Mira a fornire +pi@`u funzionalit@`a rispetto alle funzioni standard @code{sub()} e +@code{gsub()}. + +@code{gensub()} prevede una funzionalit@`a ulteriore, non disponibile in +@code{sub()} o @code{gsub()}: la possibilit@`a di specificare componenti di +una @dfn{regexp} nel testo da sostituire. Questo @`e fatto utilizzando delle +parentesi nella @dfn{regexp} per designare i componenti, e quindi inserendo +@samp{\@var{N}} nel testo di rimpiazzo, dove @var{N} @`e una cifra da 1 a 9. +Per esempio: + +@example +$ @kbd{gawk '} +> @kbd{BEGIN @{} +> @kbd{a = "abc def"} +> @kbd{b = gensub(/(.+) (.+)/, "\\2 \\1", "g", a)} +> @kbd{print b} +> @kbd{@}'} +@print{} def abc +@end example + +@noindent +Come con @code{sub()}, occorre battere due barre inverse, per ottenerne +una come componente della stringa. +Nel testo di rimpiazzo, la sequenza @samp{\0} rappresenta l'intero testo +corrispondente, e lo stesso vale per +il carattere @samp{&}. + +Il seguente esempio mostra come @`e possibile usare il terzo argomento +per controllare quale corrispondenza +della @dfn{regexp} sia da modificare: + +@example +$ @kbd{echo a b c a b c |} +> @kbd{gawk '@{ print gensub(/a/, "AA", 2) @}'} +@print{} a b c AA b c +@end example + +In questo caso, @code{$0} @`e la stringa obiettivo di default. +@code{gensub()} restituisce la nuova stringa come risultato, e questa +@`e passata direttamente a @code{print} per essere stampata. + +@c @cindex avvertimenti automatici +@c @cindex automatici, avvertimenti +Se l'argomento @var{come} @`e una stringa che non inizia con @samp{g} o +@samp{G}, o se @`e un numero minore o uguale a zero, si effettua solo una +sostituzione. Se @var{come} @`e zero, @command{gawk} emette +un messaggio di avvertimento. + +Se @var{regexp} non viene trovata in @var{obiettivo}, il valore +restituito da @code{gensub()} +@`e il valore originale e non modificato di @var{obiettivo}. + +@item @code{gsub(@var{regexp}, @var{rimpiazzo}} [@code{, @var{obiettivo}}]@code{)} +@cindexawkfunc{gsub} +Ricerca in @var{obiettivo} +@emph{tutte} le sottostringhe corrispondenti al criterio di ricerca, le +pi@`u lunghe possibili partendo da sinistra, @emph{non sovrapposte tra loro}, +e le sostituisce con @var{rimpiazzo}. +La lettera @samp{g} in @code{gsub()} significa +``global'', e richiede di sostituire dappertutto. Per esempio: + +@example +@{ gsub(/Inghilterra/, "Regno Unito"); print @} +@end example + +@noindent +sostituisce tutte le occorrenze della stringa @samp{Inghilterra} con +@samp{Regno Unito} in tutti i record in input. + +La funzione @code{gsub()} restituisce il numero di sostituzioni effettuate. +Se la variabile da cercare e modificare (@var{obiettivo}) @`e omessa, +viene usato l'intero record in input. +Come in @code{sub()}, i caratteri @samp{&} e @samp{\} sono speciali, +e il terzo argomento dev'essere modificabile. + +@item @code{index(@var{dove}, @var{cosa})} +@cindexawkfunc{index} +@cindex ricerca in stringhe +@cindex trovare sottostringhe in una stringa +Ricerca nella stringa @var{dove} la prima occorrenza della stringa @var{cosa}, +e restituisce la posizione in caratteri dell'inizio di quest'occorrenza nella +stringa @var{dove}. Si consideri il seguente esempio: + +@example +$ @kbd{awk 'BEGIN @{ print index("noccioline", "oli") @}'} +@print{} 6 +@end example + +@noindent +Se @var{cosa} non viene trovato, @code{index()} restituisce zero. + +@cindex angolo buio, @dfn{regexp} come secondo argomento di @code{index()} +In BWK @command{awk} e @command{gawk}, +@`e un errore fatale usare una costante @dfn{regexp} per @var{cosa}. +Altre implementazioni lo consentono, considerando semplicemente +la costante @dfn{regexp} come un'espressione che significa +@samp{$0 ~ /@dfn{regexp}/}. @value{DARKCORNER} + +@item @code{length(}[@var{stringa}]@code{)} +@cindexawkfunc{length} +@cindex stringa, lunghezza di una +@cindex lunghezza di una stringa +Restituisce il numero di caratteri in @var{stringa}. Se +@var{stringa} @`e un numero, viene restituita la lunghezza della stringa +di cifre che rappresenta quel numero. Per esempio, @code{length("abcde")} @`e +cinque. +Invece, @code{length(15 * 35)} restituisce tre. In questo esempio, +@iftex +@math{15 @cdot 35 = 525}, +@end iftex +@ifnottex +@ifnotdocbook +15 * 35 = 525, +@end ifnotdocbook +@end ifnottex +@docbook +15 ⋅ 35 = 525, +@end docbook +e 525 @`e quindi convertito alla stringa @code{"525"}, che @`e composta da +tre caratteri. + +@cindex lunghezza di un record in input +@cindex record in input, lunghezza di un +Se non si specifica alcun argomento, @code{length()} restituisce la +lunghezza di @code{$0}. + +@c @cindex historical features +@cindex portabilit@`a, funzione @code{length()} +@cindex POSIX @command{awk}, funzione @code{length()} e +@quotation NOTA +In alcune delle prime versioni di @command{awk}, la funzione @code{length()} +poteva essere richiamata senza alcuna parentesi. Farlo @`e considerata +una cattiva abitudine, sebbene il POSIX standard 2008 lo consenta esplicitamente, +per compatibilit@`a con la vecchia prassi. Per garantire la massima +portabilit@`a ai programmi, @`e meglio mettere sempre le parentesi. +@end quotation + +@cindex angolo buio, funzione @code{length()} +Se @code{length()} @`e chiamata con una variabile che non @`e stata usata, +@command{gawk} considera la variabile come uno scalare. Altre +implementazioni di @command{awk} non assegnano nessun tipo alla variabile. +@value{DARKCORNER} +Si consideri: + +@example +$ @kbd{gawk 'BEGIN @{ print length(x) ; x[1] = 1 @}'} +@print{} 0 +@error{} gawk: riga com.:1: fatale: tentativo di usare +@error{} scalare 'x' come vettore + +$ @kbd{nawk 'BEGIN @{ print length(x) ; x[1] = 1 @}'} +@print{} 0 +@end example + +@noindent +Se @option{--lint} @`e +stato specificato sulla riga di comando, @command{gawk} emette un +avvertimento a questo riguardo. + +@cindex estensioni comuni, @code{length()} applicato a un vettore +@cindex comuni, estensioni@comma{} @code{length()} applicato a un vettore +@cindex differenze tra @command{gawk} e @command{awk} +@cindex numero di elementi di un vettore +@cindex vettore, determinare il numero degli elementi +In @command{gawk} e in parecchie altre implementazioni @command{awk}, +se l'argomento @`e un vettore, la funzione @code{length()} restituisce il numero +di elementi nel vettore. @value{COMMONEXT} +Ci@`o @`e meno utile di quel che sembra a prima vista, in quanto +non @`e affatto detto che il vettore abbia come indici i numeri da 1 al +numero di elementi che contiene. +Se @option{--lint} @`e +stato specificato sulla riga di comando, +(@pxref{Opzioni}), +@command{gawk} avvisa che l'uso di un vettore come argomento non +@`e portabile. +Se si specifica l'opzione @option{--posix}, l'uso di un vettore come +argomento genera un errore fatale +@iftex +(@pxrefil{Vettori}). +@end iftex +@ifnottex +(@pxref{Vettori}). +@end ifnottex + +@item @code{match(@var{stringa}, @var{regexp}} [@code{, @var{vettore}}]@code{)} +@cindexawkfunc{match} +@cindex stringa, ricercare espressioni regolari in una +@cindex ricerca @dfn{regexp} in stringhe +Ricerca in @var{stringa} la +sottostringa pi@`u lunga, a partire da sinistra, che corrisponde +all'espressione regolare @var{regexp} e restituisce la posizione +del carattere (indice) con cui inizia la sottostringa (uno, se +la corrispondenza parte dall'inizio di @var{stringa}). Se non viene +trovata alcuna corrispondenza, restituisce zero. + +L'argomento @var{regexp} pu@`o essere sia una costante @dfn{regexp} +(@code{/}@dots{}@code{/}) che una costante stringa (@code{"}@dots{}@code{"}). +In quest'ultimo caso, la stringa @`e trattata come una @dfn{regexp} +per la quale cercare una corrispondenza. +@xref{Espressioni regolari calcolate} per una +spiegazione sulla differenza tra le due forme e sulle loro +implicazioni riguardo al modo per scrivere correttamente un programma. + +L'ordine dei primi due argomenti @`e l'opposto di molte altre funzioni che +trattano stringhe e che hanno a che fare con espressioni regolari, come +@code{sub()} e @code{gsub()}. Potrebbe essere di aiuto ricordare che +per @code{match()}, l'ordine @`e lo stesso che per l'operatore @samp{~} : +@samp{@var{stringa} ~ @var{regexp}}. + +@cindex @code{RSTART}, variabile, funzione @code{match()} e +@cindex variabile @code{RSTART}, funzione @code{match()} e +@cindex @code{RLENGTH}, variabile, funzione @code{match()} e +@cindex variabile @code{RLENGTH}, funzione @code{match()} e +@cindex funzione @code{match()}, variabili @code{RSTART}/@code{RLENGTH} +@cindex @code{match()}, funzione, variabili @code{RSTART}/@code{RLENGTH} +La funzione @code{match()} imposta la variabile predefinita @code{RSTART} +all'indice. +Imposta anche la variabile predefinita @code{RLENGTH} alla +lunghezza in caratteri della sottostringa individuata. Se non viene +trovata alcuna corrispondenza, @code{RSTART} @`e impostata a zero, e +@code{RLENGTH} a @minus{}1. + +Per esempio: + +@example +@c file eg/misc/findpat.awk +@{ + if ($1 == "TROVA") + regexp = $2 + else @{ + dove = match($0, regexp) + if (dove != 0) + print "Corrispondenza di", regexp, "alla posiz.", \ + dove, "in", $0 + @} +@} +@c endfile +@end example + +@noindent +Questo programma ricerca delle righe che corrispondono all'espressione +regolare contenuta nella variabile +@code{regexp}. Quest'espressione regolare pu@`o essere modificata. Se la +prima parola in una riga @`e @samp{TROVA}, @code{regexp} diventa la +seconda parola su quella riga. Quindi, dato: + +@example +@c file eg/misc/findpat.data +TROVA or+e +Il mio programma corre +ma non troppo velocemente +TROVA Melvin +JF+KM +Questa riga appartiene a Reality Engineering Co. +Melvin @`e passato da qui. +@c endfile +@end example + +@noindent +@command{awk} stampa: + +@example +Corrispondenza di or+e alla posiz. 19 in Il mio programma corre +Corrispondenza di Melvin alla posiz. 1 in Melvin @`e passato da qui. +@end example + +@cindex differenze tra @command{awk} e @command{gawk}, funzione @code{match()} +Se @var{vettore} esiste gi@`a, viene cancellato, e quindi l'elemento numero +zero di @var{vettore} @`e impostato all'intera parte di @var{stringa} +individuata da @var{regexp}. Se @var{regexp} contiene parentesi, +gli elementi aventi per indici numeri interi in @var{vettore} sono +impostati per contenere ognuno la parte di @var{stringa} individuata dalla +corrispondente sottoespressione delimitata da parentesi. +Per esempio: + +@example +$ @kbd{echo pippoooopaperpluttttttt |} +> @kbd{gawk '@{ match($0, /(pippo+).+(plut*)/, vett)} +> @kbd{print vett[1], vett[2] @}'} +@print{} pippoooo pluttttttt +@end example + +Inoltre, +sono disponibili indici multidimensionali che contengono +la posizione di partenza e la lunghezza di ogni sottoespressione +individuata: + +@example +$ @kbd{echo pippoooopaperpluttttttt |} +> @kbd{gawk '@{ match($0, /(pippo+).+(plut*)/, vett)} +> @kbd{print vett[1], vett[2]} +> @kbd{print vett[1, "start"], vett[1, "length"]} +> @kbd{print vett[2, "start"], vett[2, "length"]} +> @kbd{@}'} +@print{} pippoooo pluttttttt +@print{} 1 8 +@print{} 14 10 +@end example + +Possono non esserci indici che individuino inizio e posizione +per ogni sottoespressione +fra parentesi, perch@'e non tutte potrebbero aver individuato del testo; +quindi, andrebbero esaminati usando l'operatore @code{in} +(@pxref{Visitare elementi}). + +@cindex risoluzione di problemi, funzione @code{match()} +@cindex problemi, risoluzione di, funzione @code{match()} +L'argomento @var{vettore} di @code{match()} @`e un'estensione +@command{gawk}. In modalit@`a compatibile +(@pxref{Opzioni}), +l'impiego di un terzo argomento causa un errore fatale. + +@item @code{patsplit(@var{stringa}, @var{vettore}} [@code{, @var{regexpdelim}} [@code{, @var{separatori}} ] ]@code{) #} +@cindexgawkfunc{patsplit} +@cindex dividere in un vettore una stringa +@cindex creare un vettore da una stringa +Divide +@var{stringa} in parti definite da @var{regexpdelim} +e memorizza i pezzi in @var{vettore} e le stringhe di separazione nel +vettore @var{separatori}. Il primo pezzo @`e memorizzato in +@code{@var{vettore}[1]}, il secondo pezzo in @code{@var{vettore}[2]}, e +cos@`{@dotless{i}} via. Il terzo argomento, @var{regexpdelim}, @`e +una @dfn{regexp} che descrive i campi in @var{stringa} (allo stesso modo in +cui @code{FPAT} @`e una @dfn{regexp} che descrive i campi nei record +in input). +Pu@`o essere una costante @dfn{regexp} o una stringa. +Se @var{regexpdelim} @`e omesso, viene usato il valore di @code{FPAT}. +@code{patsplit()} restituisce il numero di elementi creati. +@code{@var{separatori}[@var{i}]} @`e +la stringa che separa +l'elemento @code{@var{vettore}[@var{i}]} e @code{@var{vettore}[@var{i}+1]}. +Ogni separatore iniziale sar@`a in @code{@var{separatori}[0]}. + +La funzione @code{patsplit()} divide delle stringhe in pezzi in modo +simile a quello con cui le righe in input vengono divise in campi +usando @code{FPAT} +(@pxref{Separazione in base al contenuto}). + +Prima di dividere la stringa, @code{patsplit()} cancella ogni elemento che +fosse eventualmente presente +nei vettori @var{vettore} e @var{separatori}. + +@item @code{split(@var{stringa}, @var{vettore}} [@code{, @var{separacampo}} [@code{, @var{separatori}} ] ]@code{)} +@cindexawkfunc{split} +Divide @var{stringa} in pezzi separati da @var{separacampo} +e memorizza i pezzi in @var{vettore} e le stringhe di separazione nel +vettore @var{separatori}. Il primo pezzo @`e memorizzato in +@code{@var{vettore}[1]}, il secondo pezzo in @code{@var{vettore}[2]}, e +cos@`{@dotless{i}} via. Il valore della stringa specificata nel terzo argomento, +@var{separacampo}, @`e una @dfn{regexp} che indica come dividere @var{stringa} +(analogamente a come @code{FS} pu@`o essere un @dfn{regexp} che indica dove +dividere i record in input). +Se @var{separacampo} @`e omesso, si usa il valore di @code{FS}. +@code{split()} restituisce il numero di elementi creati. +@var{separatori} @`e un'estensione @command{gawk}, in cui +@code{@var{separatori}[@var{i}]} +@`e la stringa che separa @code{@var{vettore}[@var{i}]} e +@code{@var{vettore}[@var{i}+1]}. +Se @var{separacampo} @`e uno spazio bianco, ogni eventuale spazio bianco +a inizio stringa viene messo in @code{@var{separatori}[0]} e ogni +eventuale spazio bianco a fine stringa viene messo in +@code{@var{separatori}[@var{n}]}, dove @var{n} @`e il valore restituito da +@code{split()} (cio@`e il numero di elementi in @var{vettore}). + +La funzione @code{split()} divide le stringhe in pezzi in modo simile +a quello con cui le righe in input sono divise in campi. Per esempio: + +@example +split("cul-de-sac", a, "-", separatori) +@end example + +@noindent +@cindex stringhe, divisione, esempio +divide la stringa @code{"cul-de-sac"} in tre campi usando @samp{-} come +separatore. Il vettore @code{a} ha i seguenti contenuti: + +@example +a[1] = "cul" +a[2] = "de" +a[3] = "sac" +@end example + +e imposta il contenuto del vettore @code{separatori} come segue: + +@example +seps[1] = "-" +seps[2] = "-" +@end example + +@noindent +Il valore restituito da questa chiamata a @code{split()} @`e tre. + +@cindex differenze tra @command{awk} e @command{gawk}, funzione @code{split()} +Come nella divisione in campi dei record in input, quando il valore di +@var{separacampo} @`e @w{@code{" "}}, gli spazi bianchi a inizio e fine stringa +vengono ignorati nell'assegnare valori agli elementi di @var{vettore} ma non nel +vettore @var{separatori}, e gli elementi sono separati da uno o pi@`u spazi +bianchi. Inoltre, come nel caso della divisione dei record in input, se +@var{separacampo} @`e la stringa nulla, ogni singolo carattere nella stringa +costituisce un elemento del vettore. +@value{COMMONEXT} + +Si noti, tuttavia, che @code{RS} non influisce sul comportamento di +@code{split()}. +Anche se @samp{RS = ""} fa s@`{@dotless{i}} che il carattere di ritorno a capo sia un +separatore di campo, +questo non influenza il modo in cui @code{split()} divide le stringhe. + +@cindex angolo buio, funzione @code{split()} +Recenti implementazioni di @command{awk}, incluso @command{gawk}, +consentono che il terzo argomento sia una costante @dfn{regexp} +(@w{@code{/}@dots{}@code{/}}) +o anche una stringa. @value{DARKCORNER} +Anche lo standard POSIX permette questo. +@xref{Espressioni regolari calcolate} per la spiegazione della differenza +tra l'uso di una costante stringa e l'uso di una costante @dfn{regexp}, +sulle loro implicazioni riguardo a come scrivere correttamente un programma. + +Prima di dividere la stringa, @code{split()} cancella ogni elemento +eventualmente gi@`a presente +nei vettori @var{vettore} e @var{separatori}. + +Se @var{stringa} @`e la stringa nulla, il vettore non ha elementi. +(Quindi, in questo modo si pu@`o cancellare un intero vettore con una sola +istruzione). +@xref{Cancellazione}.) + +Se in @var{stringa} non viene trovato @var{separacampo} (ma la stringa +non @`e la stringa nulla), +@var{vettore} ha solo un elemento. Il valore di quell'elemento @`e la +@var{stringa} originale. + +In modalit@`a POSIX (@pxref{Opzioni}), il quarto argomento non @`e disponibile. + +@item @code{sprintf(@var{formato}, @var{espressione1}, @dots{})} +@cindexawkfunc{sprintf} +@cindex formattare stringhe +@cindex stringhe, formattazione +Restituisce (senza stamparla) la stringa che @code{printf} avrebbe +stampato con gli stessi argomenti +(@pxref{Printf}). +Per esempio: + +@example +pival = sprintf("pi = %.2f (approx.)", 22/7) +@end example + +@noindent +assegna la stringa @w{@samp{pi = 3.14 (approx.)}} alla variabile @code{pival}. + +@cindexgawkfunc{strtonum} +@cindex conversione di una stringa in un numero +@cindex stringhe, conversione in numeri +@item @code{strtonum(@var{stringa}) #} +Esamina @var{stringa} e restituisce il suo valore numerico. Se +@var{stringa} inizia con la cifra @samp{0}, @code{strtonum()} presuppone +che @var{stringa} sia un numero ottale. Se @var{stringa} inizia con +@samp{0x} o @samp{0X}, @code{strtonum()} presuppone che @var{stringa} sia un +numero esadecimale. +Per esempio: + +@example +$ @kbd{echo 0x11 |} +> @kbd{gawk '@{ printf "%d\n", strtonum($1) @}'} +@print{} 17 +@end example + +Usare la funzione @code{strtonum()} @emph{non} @`e lo stesso che aggiungere +zero al valore di una stringa; +la conversione automatica di stringhe in numeri +si applica solo a dati decimali, non a quelli ottali o +esadecimali.@footnote{Tranne nel caso si usi l'opzione +@option{--non-decimal-data}, il che non @`e consigliato. +@xref{Dati non decimali} per ulteriori informazioni.} + +Si noti anche che @code{strtonum()} usa il separatore decimale della +localizzazione corrente per riconoscere i numeri +(@pxref{Localizzazioni}). + +@item @code{sub(@var{regexp}, @var{rimpiazzo}} [@code{, @var{obiettivo}}]@code{)} +@cindexawkfunc{sub} +@cindex rimpiazzare in una stringa +@cindex stringa, rimpiazzare in una +Ricerca in @var{obiettivo}, che @`e visto come una stringa, +la prima sottostringa pi@`u lunga possibile, +a partire da sinistra, che corrisponde all'espressione regolare @var{regexp}. +Modifica l'intera stringa sostituendo il testo individuato con +@var{rimpiazzo}. +La stringa cos@`{@dotless{i}} modificata diventa il nuovo valore di @var{obiettivo}. +Restituisce il numero di sostituzioni fatte (zero o uno). + +L'argomento @var{regexp} pu@`o essere o una costante @dfn{regexp} +(@code{/}@dots{}@code{/}) o una constante stringa (@code{"}@dots{}@code{"}). +In quest'ultimo caso, la stringa @`e trattata come una @dfn{regexp} +da individuare. +@xref{Espressioni regolari calcolate} per la spiegazione della differenza tra +le due forme, delle loro implicazioni riguardo al modo di scrivere +correttamente un programma. + +Questa funzione @`e particolare perch@'e @var{obiettivo} non @`e semplicemente usato +per calcolare un valore, e non basta che sia un'espressione qualsiasi: +dev'essere una variabile, un campo, o un elemento di vettore in cui +@code{sub()} possa memorizzare un valore modificato. Se questo argomento @`e +omesso, il comportamento di default @`e +quello di usare e modificare +@code{$0}.@footnote{Si noti che questo significa che il record sar@`a dapprima +ricostruito, usando il valore di @code{OFS} se qualche campo @`e stato cambiato, +e che i campi saranno aggiornati dopo la sostituzione, anche se l'operazione in +s@'e non cambia il record (@`e una ``no-op'') come @samp{sub(/^/, "")}.} Per +esempio: + +@example +str = "acqua, acqua dappertutto" +sub(/cqu/, "vari", str) +@end example + +@noindent +modifica @code{stringa} facendola divenire +@w{@samp{avaria, acqua dappertutto}}, +rimpiazzando l'occorrenza pi@`u lunga, +a partire da sinistra, di @samp{cqu} con @samp{vari}. + +Se il carattere speciale @samp{&} compare in @var{rimpiazzo}, designa +l'esatta sottostringa individuata da @var{regexp}. (Se +@dfn{regexp} pu@`o individuare pi@`u di una stringa, questa sottostringa +pu@`o assumere valori diversi.) Per esempio: + +@example +@{ sub(/candidato/, "& e sua moglie"); print @} +@end example + +@noindent +cambia la prima occorrenza di @samp{candidato} a @samp{candidato +e sua moglie} in ogni riga in input. +Ecco un altro esempio: + +@example +$ @kbd{awk 'BEGIN @{} +> @kbd{str = "daabaaa"} +> @kbd{sub(/a+/, "C&C", str)} +> @kbd{print str} +> @kbd{@}'} +@print{} dCaaCbaaa +@end example + +@noindent +questo mostra come @samp{&} possa rappresentare una stringa variabile +e illustra anche la regola +``a partire da sinistra, la pi@`u lunga'' nell'individuazione di @dfn{regexp} +(@pxref{Pi@`u lungo da sinistra}). + +L'effetto di questo carattere speciale (@samp{&}) pu@`o essere neutralizzato +anteponendogli una barra inversa nella stringa. Come al solito, per +inserire una barra inversa nella +stringa, occorre scrivere due barre inverse. Quindi, occorre scrivere +@samp{\\&} in una costante stringa per includere un carattere @samp{&} +nel rimpiazzo. +Per esempio, quanto segue mostra come rimpiazzare il primo @samp{|} su +ogni riga con un @samp{&}: + +@example +@{ sub(/\|/, "\\&"); print @} +@end example + +@cindex @code{sub()}, funzione, argomenti di +@cindex funzione @code{sub()}, argomenti di +@cindex @code{gsub()}, funzione, argomenti di +@cindex funzione @code{gsub()}, argomenti di +Come gi@`a accennato, il terzo argomento di @code{sub()} dev'essere +una variabile, un campo, o un elemento di vettore. +Alcune versioni di @command{awk} accettano come terzo argomento +un'espressione che non @`e un @dfn{lvalue}. In tal caso, @code{sub()} +cerca ugualmente l'espressione e restituisce zero o uno, ma il risultato +della sostituzione (se ce n'@`e uno) viene scartato perch@'e non c'@`e un posto +dove memorizzarlo. Tali versioni di @command{awk} accettano espressioni +come le seguente: + +@example +sub(/USA/, "Stati Uniti", "gli USA e il Canada") +@end example + +@noindent +@cindex risoluzione di problemi, funzioni @code{gsub()}/@code{sub()} +@cindex problemi, risoluzione di, funzioni @code{gsub()}/@code{sub()} +Per compatibilit@`a storica, @command{gawk} accetta un tale codice erroneo. +Tuttavia, l'uso di qualsiasi altra espressione non modificabile +come terzo parametro causa un errore fatale, e il programma +non viene portato a termine. + +Infine, se la @var{regexp} non @`e una costante @dfn{regexp}, @`e convertita +in una stringa, e quindi il valore di quella stringa @`e trattato come +la @dfn{regexp} da individuare. + +@item @code{substr(@var{stringa}, @var{inizio}} [@code{, @var{lunghezza}} ]@code{)} +@cindexawkfunc{substr} +@cindex sottostringa +Restituisce una sottostringa di @var{stringa} lunga @var{lunghezza} caratteri, +iniziando dal carattere numero @var{inizio}. Il primo carattere di una +stringa @`e il carattere numero uno.@footnote{Questo @`e differente da +C e C++, in cui il primo carattere ha il numero zero.} +Per esempio, @code{substr("Washington", 5, 3)} restituisce @code{"ing"}. + +Se @var{lunghezza} non @`e presente, @code{substr()} restituisce l'intero +suffisso di +@var{stringa} a partire dal carattere numero @var{inizio}. Per esempio, +@code{substr("Washington", 5)} restituisce @code{"ington"}. L'intero +suffisso @`e restituito anche +se @var{lunghezza} @`e maggiore del numero di caratteri disponibili +nella stringa, a partire dal carattere @var{inizio}. + +@cindex Brian Kernighan, @command{awk} di +Se @var{inizio} @`e minore di uno, @code{substr()} lo tratta come se +fosse uno. (POSIX non specifica cosa fare in questo caso: +BWK @command{awk} si comporta cos@`{@dotless{i}}, e quindi @command{gawk} fa lo stesso.) +Se @var{inizio} @`e maggiore del numero di caratteri +nella stringa, @code{substr()} restituisce la stringa nulla. +Analogamente, se @var{lunghezza} @`e presente ma minore o uguale a zero, +viene restituita la stringa nulla. + +@cindex risoluzione di problemi, funzione @code{substr()} +@cindex problemi, risoluzione di, funzione @code{substr()} +La stringa restituita da @code{substr()} @emph{non pu@`o} essere +assegnata. Quindi, @`e un errore tentare di modificare una porzione di +una stringa, come si vede nel seguente esempio: + +@example +stringa = "abcdef" +# tentare di ottenere "abCDEf", non @`e possibile +substr(stringa, 3, 3) = "CDE" +@end example + +@noindent +@`E anche un errore usare @code{substr()} come terzo argomento +di @code{sub()} o @code{gsub()}: + +@example +gsub(/xyz/, "pdq", substr($0, 5, 20)) # SBAGLIATO +@end example + +@cindex portabilit@`a, funzione @code{substr()} +(Alcune versioni commerciali di @command{awk} consentono un tale uso di +@code{substr()}, ma un tale codice non @`e portabile.) + +Se si devono sostituire pezzi di una stringa, +si combini @code{substr()} +con una concatenazione di stringa, nel modo seguente: + +@example +stringa = "abcdef" +@dots{} +stringa = substr(stringa, 1, 2) "CDE" substr(stringa, 6) +@end example + +@cindex maiuscolo/minuscolo, conversione da/a +@cindex stringhe, convertire maiuscolo/minuscolo +@item @code{tolower(@var{stringa})} +@cindexawkfunc{tolower} +@cindex convertire stringa in minuscolo +Restituisce una copia di @var{stringa}, con ogni carattere maiuscolo +nella stringa rimpiazzato dal suo corrispondente carattere minuscolo. +I caratteri non alfabetici non vengono modificati. Per esempio, +@code{tolower("MaIuScOlO MiNuScOlO 123")} restituisce +@code{"maiuscolo minuscolo 123"}. + +@item @code{toupper(@var{stringa})} +@cindexawkfunc{toupper} +@cindex convertire stringa in maiuscolo +Restituisce una copia di @var{stringa}, con ogni carattere minuscolo +nella stringa rimpiazzato dal suo corrispondente carattere maiuscolo. +I caratteri non alfabetici non vengono modificati. Per esempio, +@code{tolower("MaIuScOlO MiNuScOlO 123")} restituisce +@code{"MAIUSCOLO MINUSCOLO 123"}. +@end table + +@sidebar Individuare la stringa nulla +@cindex individuare la stringa nulla +@cindex stringa nulla, individuare la +@cindex @code{*} (asterisco), operatore @code{*}, individuare la stringa nulla +@cindex asterisco (@code{*}), operatore @code{*}, individuare la stringa nulla + +In @command{awk}, l'operatore @samp{*} pu@`o individuare la stringa nulla. +Questo @`e particolarmente importante per le funzioni @code{sub()}, +@code{gsub()} e @code{gensub()}. Per esempio: + +@example +$ @kbd{echo abc | awk '@{ gsub(/m*/, "X"); print @}'} +@print{} XaXbXcX +@end example + +@noindent +Sebbene questo sia abbastanza sensato, pu@`o suscitare una certa sorpresa. +@end sidebar + + +@node Dettagli ostici +@subsubsection Ulteriori dettagli su @samp{\} e @samp{&} con @code{sub()}, @code{gsub()} e @code{gensub()} + +@cindex protezione caratteri nelle funzioni @code{gsub()}/@code{gensub()}/@code{sub()} +@cindex funzione @code{sub()}, protezione caratteri +@cindex @code{sub()}, funzione, protezione caratteri +@cindex funzione @code{gsub()}, protezione caratteri +@cindex @code{gsub()}, funzione, protezione caratteri +@cindex funzione @code{gensub()} (@command{gawk}), protezione caratteri +@cindex @code{gensub()}, funzione (@command{gawk}), protezione caratteri +@cindex @code{\} (barra inversa), @code{gsub()}/@code{gensub()}/@code{sub()} funzioni e +@cindex barra inversa (@code{\}), @code{gsub()}/@code{gensub()}/@code{sub()} funzioni e +@cindex @code{&} (e commerciale), funzioni @code{gsub()}/@code{gensub()}/@code{sub()} e +@cindex e commerciale (@code{&}), funzioni @code{gsub()}/@code{gensub()}/@code{sub()} e + +@quotation ATTENZIONE +Si dice che questa sottosezione possa causare dei mal di testa. +In prima lettura pu@`o essere benissimo saltata. +@end quotation + +Quando si usa @code{sub()}, @code{gsub()} o @code{gensub()}, e si +desidera includere delle +barre inverse e delle "e commerciali" (@code{&}) nel testo da sostituire +@`e necessario ricordare che ci sono parecchi livelli di +@dfn{protezione caratteri} in gioco. + +Anzitutto, vi @`e il livello @dfn{lessicale}, quello in cui @command{awk} +legge un programma e ne costruisce una copia interna da eseguire. +Poi c'@`e il momento dell'esecuzione, quello in cui @command{awk} +esamina effettivamente la stringa da sostituire, per determinare cosa +fare. + +@cindex Brian Kernighan, @command{awk} di +In entrambi i livelli, @command{awk} ricerca un dato insieme di caratteri +che possono venire dopo una +barra inversa. A livello lessicale, cerca le sequenze di protezione +elencate in @ref{Sequenze di protezione}. +Quindi, per ogni @samp{\} che @command{awk} elabora al momento +dell'esecuzione, occorre immetterne due a livello lessicale. +Quando un carattere che non ha necessit@`a di una sequenza di protezione +segue una @samp{\}, sia BWK @command{awk} che @command{gawk} semplicemente +rimuovono la @samp{\} stessa e +mettono il carattere seguente nella stringa. Quindi, per esempio, +@code{"a\qb"} @`e trattato come se si fosse scritto @code{"aqb"}. + +Al momento dell'esecuzione, le varie funzioni gestiscono sequenze di +@samp{\} e @samp{&} in maniera differente. La situazione @`e (purtroppo) +piuttosto complessa. +Storicamente, le funzioni @code{sub()} e @code{gsub()} trattavano la +sequenza di due caratteri @samp{\&} in maniera speciale; questa sequenza +era rimpiazzata nel testo +generato da un singolo carattere @samp{&}. Ogni altra @samp{\} contenuta +nella stringa @var{rimpiazzo} che non era posta prima di una @samp{&} era +lasciata passare senza modifiche. +Questo @`e illustrato nella @ref{table-sub-escapes}. + +@c Thank to Karl Berry for help with the TeX stuff. +@float Tabella,table-sub-escapes +@caption{Elaborazione storica delle sequenze di protezione per @code{sub()} e @code{gsub()}} +@tex +\vbox{\bigskip +% We need more characters for escape and tab ... +\catcode`_ = 0 +\catcode`! = 4 +% ... since this table has lots of &'s and \'s, so we unspecialize them. +\catcode`\& = \other \catcode`\\ = \other +_halign{_hfil#!_qquad_hfil#!_qquad#_hfil_cr + Immissione!@code{sub()} vede!@code{sub()} genera_cr +_hrulefill!_hrulefill!_hrulefill_cr + @code{\&}! @code{&}!Il testo individuato_cr + @code{\\&}! @code{\&}!Il carattere @samp{&}_cr + @code{\\\&}! @code{\&}!Il carattere @samp{&}_cr + @code{\\\\&}! @code{\\&}!I caratteri @samp{\&}_cr + @code{\\\\\&}! @code{\\&}!I caratteri @samp{\&}_cr +@code{\\\\\\&}! @code{\\\&}!I caratteri @samp{\\&}_cr + @code{\\q}! @code{\q}!I caratteri @samp{\q}_cr +} +_bigskip} +@end tex +@ifdocbook +@multitable @columnfractions .20 .20 .60 +@headitem Immissione @tab @code{sub()} vede @tab @code{sub()} genera +@item @code{\&} @tab @code{&} @tab Il testo individuato +@item @code{\\&} @tab @code{\&} @tab Il carattere @samp{&} +@item @code{\\\&} @tab @code{\&} @tab Il carattere @samp{&} +@item @code{\\\\&} @tab @code{\\&} @tab I caratteri @samp{\&} +@item @code{\\\\\&} @tab @code{\\&} @tab I caratteri @samp{\&} +@item @code{\\\\\\&} @tab @code{\\\&} @tab I caratteri @samp{\\&} +@item @code{\\q} @tab @code{\q} @tab I caratteri @samp{\q} +@end multitable +@end ifdocbook +@ifnottex +@ifnotdocbook +@display + Immissione @code{sub()} vede @code{sub()} genera + --------------- ------------- --------------- + @code{\&} @code{&} Il testo individuato + @code{\\&} @code{\&} La lettera @samp{&} + @code{\\\&} @code{\&} La lettera @samp{&} + @code{\\\\&} @code{\\&} Le lettere @samp{\&} + @code{\\\\\&} @code{\\&} Le lettere @samp{\&} +@code{\\\\\\&} @code{\\\&} Le lettere @samp{\\&} + @code{\\q} @code{\q} Le lettere @samp{\q} +@end display +@end ifnotdocbook +@end ifnottex +@end float + +@noindent +Questa tabella mostra l'elaborazione a livello lessicale, in cui +un numero dispari di barre inverse diventa un numero pari al momento +dell'esecuzione, +e mostra anche l'elaborazione in fase di esecuzione fatta da @code{sub()}. +(Per amor di semplicit@`a le tavole che ancora seguono mostrano solo il caso +di un numero pari di barre inverse immesso a livello lessicale.) + +Il problema con l'approccio storico @`e che non c'@`e modo di ottenere +un carattere @samp{\} seguito dal testo individuato. + +Parecchie edizioni dello standard POSIX hanno provato a risolvere questo +problema, senza riuscirci. I dettagli sono irrilevanti in questo contesto. + +A un certo punto, il manutentore di @command{gawk} ha presentato una +proposta per una revisione dello standard per tornare +a regole che corrispondano pi@`u da vicino alla prassi originalmente seguita. +Le regole proposte hanno dei casi speciali che rendono possibile +produrre una @samp{\} prima del +testo individuato. Questo si pu@`o vedere nella +@ref{table-sub-proposed}. + +@float Tabella,table-sub-proposed +@caption{Regole @command{gawk} per @code{sub()} e barra inversa} +@tex +\vbox{\bigskip +% We need more characters for escape and tab ... +\catcode`_ = 0 +\catcode`! = 4 +% ... since this table has lots of &'s and \'s, so we unspecialize them. +\catcode`\& = \other \catcode`\\ = \other +_halign{_hfil#!_qquad_hfil#!_qquad#_hfil_cr + Immissione!@code{sub()} vede!@code{sub()} genera_cr +_hrulefill!_hrulefill!_hrulefill_cr +@code{\\\\\\&}! @code{\\\&}!I caratteri @samp{\&}_cr +@code{\\\\&}! @code{\\&}!Il carattere @samp{\}, seguito dal testo individuato_cr + @code{\\&}! @code{\&}!Il carattere @samp{&}_cr + @code{\\q}! @code{\q}!I caratteri @samp{\q}_cr + @code{\\\\}! @code{\\}!@code{\\}_cr +} +_bigskip} +@end tex +@ifdocbook +@multitable @columnfractions .20 .20 .60 +@headitem Immissione @tab @code{sub()} vede @tab @code{sub()} genera +@item @code{\\\\\\&} @tab @code{\\\&} @tab I caratteri @samp{\&} +@item @code{\\\\&} @tab @code{\\&} @tab Il carattere @samp{\}, seguito dal testo individuato +@item @code{\\&} @tab @code{\&} @tab Il carattere @samp{&} +@item @code{\\q} @tab @code{\q} @tab I caratteri @samp{\q} +@item @code{\\\\} @tab @code{\\} @tab @code{\\} +@end multitable +@end ifdocbook +@ifnottex +@ifnotdocbook +@display +Immissione @code{sub()} vede @code{sub()} genera +--------- ---------- --------------- +@code{\\\\\\&} @code{\\\&} Il carattere @samp{\&} + @code{\\\\&} @code{\\&} Il carattere @samp{\}, seguito dal testo individuato + @code{\\&} @code{\&} Il carattere @samp{&} + @code{\\q} @code{\q} I caratteri @samp{\q} + @code{\\\\} @code{\\} @code{\\} +@end display +@end ifnotdocbook +@end ifnottex +@end float + +In breve, al momento dell'esecuzione, ci sono ora tre sequenze speciali +di caratteri (@samp{\\\&}, @samp{\\&}, e @samp{\&}) mentre tradizionalmente +ce n'era una sola. Tuttavia, come nel caso storico, ogni @samp{\} che +non fa parte di una di queste tre sequenze non @`e speciale e appare +nell'output cos@`{@dotless{i}} come @`e scritto. + +@command{gawk} 3.0 e 3.1 seguono queste regole per @code{sub()} e +@code{gsub()}. La revisione dello standard POSIX ha richiesto molto pi@`u tempo +di quel che ci si attendeva. Inoltre, la proposta del manutentore di +@command{gawk} @`e andata persa durante il processo di standardizzazione. Le +regole finali risultanti sono un po' pi@`u semplici. I risultati sono simili, +tranne che in un caso. + +@cindex POSIX @command{awk}, funzioni @code{gsub()}/@code{sub()} e +Le regole POSIX stabiliscono che @samp{\&} nella stringa di rimpiazzo +produca il carattere @samp{&}, @samp{\\} produce il carattere @samp{\}, +e che @samp{\} seguito da qualsiasi carattere non @`e speciale; la @samp{\} +@`e messa direttamente nell'output. +Queste regole sono presentate nella @ref{table-posix-sub}. + +@float Tabella,table-posix-sub +@caption{Regole POSIX per @code{sub()} e @code{gsub()}} +@tex +\vbox{\bigskip +% We need more characters for escape and tab ... +\catcode`_ = 0 +\catcode`! = 4 +% ... since this table has lots of &'s and \'s, so we unspecialize them. +\catcode`\& = \other \catcode`\\ = \other +_halign{_hfil#!_qquad_hfil#!_qquad#_hfil_cr + Immissione!@code{sub()} vede!@code{sub()} genera_cr +_hrulefill!_hrulefill!_hrulefill_cr +@code{\\\\\\&}! @code{\\\&}!I caratteri @samp{\&}_cr +@code{\\\\&}! @code{\\&}!Il carattere @samp{\}, seguito dal testo individuato_cr + @code{\\&}! @code{\&}!Il carattere @samp{&}_cr + @code{\\q}! @code{\q}!I caratteri @samp{\q}_cr + @code{\\\\}! @code{\\}!@code{\}_cr +} +_bigskip} +@end tex +@ifdocbook +@multitable @columnfractions .20 .20 .60 +@headitemImmissione @tab @code{sub()} vede @tab @code{sub()} genera +@item @code{\\\\\\&} @tab @code{\\\&} @tab I caratteri @samp{\&} +@item @code{\\\\&} @tab @code{\\&} @tab Il carattere @samp{\}, seguito dal testo individuato +@item @code{\\&} @tab @code{\&} @tab I caratteri @samp{&} +@item @code{\\q} @tab @code{\q} @tab I caratteri @samp{\q} +@item @code{\\\\} @tab @code{\\} @tab @code{\} +@end multitable +@end ifdocbook +@ifnottex +@ifnotdocbook +@display +Immissione @code{sub()} vede @code{sub()} genera +--------- ---------- --------------- +@code{\\\\\\&} @code{\\\&} I caratteri @samp{\&} + @code{\\\\&} @code{\\&} Il carattere @samp{\}, seguito dal testo individuato + @code{\\&} @code{\&} Il carattere @samp{&} + @code{\\q} @code{\q} I caratteri @samp{\q} + @code{\\\\} @code{\\} @code{\} +@end display +@end ifnotdocbook +@end ifnottex +@end float + +Il solo caso in cui la differenza @`e rilevante @`e l'ultimo: @samp{\\\\} +@`e visto come @samp{\\} e produce @samp{\} invece che @samp{\\}. + +A partire dalla @value{PVERSION} 3.1.4, @command{gawk} ha seguito le regole +POSIX quando si specifica @option{--posix} (@pxref{Opzioni}). Altrimenti, ha +continuato a seguire le regole proposte [a POSIX], poich@'e questa @`e stato il +comportamento seguito per parecchi anni. + +Quando la @value{PVERSION} 4.0.0 @`e stata rilasciata, il manutentore di +@command{gawk} +ha stabilito come default le regole POSIX, interrompendo cos@`{@dotless{i}} oltre +un decennio di compatibilit@`a +all'indietro.@footnote{Questa decisione si @`e dimostrata piuttosto avventata, +anche se una nota in questa sezione avvertiva che la successiva versione +principale di @command{gawk} avrebbe adottato le regole POSIX.} +Inutile dire che questa non @`e stata una buona idea, e quindi dalla +@value{PVERSION} 4.0.1, @command{gawk} ha ripreso il suo comportamento +tradizionale, seguendo le regole POSIX solo quando si specifica l'opzione +@option{--posix}. + +Le regole per @code{gensub()} sono molto pi@`u semplici. Al momento +dell'esecuzione, quando @command{gawk} vede una @samp{\}, se il carattere +seguente @`e una cifra, +il testo individuato dalla corrispondente sottoespressione tra parentesi +@`e inserito nell'output generato. Altrimenti, qualsiasi carattere segua la +@samp{\} viene inserito nel testo generato, mentre la @samp{\} va persa, +come si vede nella @ref{table-gensub-escapes}. + +@float Tabella,table-gensub-escapes +@caption{Elaborazione sequenze di protezione in @code{gensub()}} +@tex +\vbox{\bigskip +% We need more characters for escape and tab ... +\catcode`_ = 0 +\catcode`! = 4 +% ... since this table has lots of &'s and \'s, so we unspecialize them. +\catcode`\& = \other \catcode`\\ = \other +_halign{_hfil#!_qquad_hfil#!_qquad#_hfil_cr + Immissione!@code{gensub()} vede!@code{gensub()} genera_cr +_hrulefill!_hrulefill!_hrulefill_cr + @code{&}! @code{&}!Il testo individuato_cr + @code{\\&}! @code{\&}!Il carattere @samp{&}_cr + @code{\\\\}! @code{\\}!Il carattere @samp{\}_cr + @code{\\\\&}! @code{\\&}!Il carattere @samp{\}, seguito dal testo individuato_cr +@code{\\\\\\&}! @code{\\\&}!I caratteri @samp{\&}_cr + @code{\\q}! @code{\q}!Il carattere @samp{q}_cr +} +_bigskip} +@end tex +@ifdocbook +@multitable @columnfractions .20 .20 .60 +@headitem Immissione @tab @code{gensub()} vede @tab @code{gensub()} genera +@item @code{&} @tab @code{&} @tab Il testo individuato +@item @code{\\&} @tab @code{\&} @tab Il carattere @samp{&} +@item @code{\\\\} @tab @code{\\} @tab Il carattere @samp{\} +@item @code{\\\\&} @tab @code{\\&} @tab Il carattere @samp{\}, seguito dal testo individuato +@item @code{\\\\\\&} @tab @code{\\\&} @tab I caratteri @samp{\&} +@item @code{\\q} @tab @code{\q} @tab Il carattere @samp{q} +@end multitable +@end ifdocbook +@ifnottex +@ifnotdocbook +@display + Immissione @code{gensub()} vede @code{gensub()} genera + --------- ------------- ------------------ + @code{&} @code{&} Il testo individuato + @code{\\&} @code{\&} Il carattere @samp{&} + @code{\\\\} @code{\\} Il carattere @samp{\} + @code{\\\\&} @code{\\&} Il carattere @samp{\}, seguito dal testo individuato +@code{\\\\\\&} @code{\\\&} I caratteri @samp{\&} + @code{\\q} @code{\q} Il carattere @samp{q} +@end display +@end ifnotdocbook +@end ifnottex +@end float + +A causa della complessit@`a dell'elaborazione a livello lessicale e in fase +di esecuzione, e dei casi speciali di @code{sub()} e @code{gsub()}, +si raccomanda l'uso di @command{gawk} e di @code{gensub()} quando ci siano +da fare delle sostituzioni. + +@node Funzioni di I/O +@subsection Funzioni di Input/Output +@cindex input/output, funzioni di +@cindex funzioni di input/output + +Le seguenti funzioni riguardano l'input/output (I/O). +I parametri facoltativi sono racchiusi tra parentesi quadre ([ ]): + +@table @asis +@item @code{close(}@var{nome_file} [@code{,} @var{come}]@code{)} +@cindexawkfunc{close} +@cindex file, chiusura +@cindex chiudere un file o un coprocesso +Chiude il file @var{nome_file} in input o in output. Alternativamente, +l'argomento pu@`o essere un comando della shell usato per creare un +coprocesso, o per ridirigere +verso o da una @dfn{pipe}; questo coprocesso o @dfn{pipe} viene chiuso. +@xref{Chiusura file e @dfn{pipe}} +per ulteriori informazioni. + +Quando si chiude un coprocesso, pu@`o talora essere utile chiudere dapprima +un lato della @dfn{pipe} bidirezionale e quindi chiudere l'altro. +Questo si pu@`o fare fornendo un secondo argomento a @code{close()}. +Questo secondo argomento (@var{come}) +dovrebbe essere una delle due stringhe @code{"to"} o @code{"from"}, +che indicano quale lato della @dfn{pipe} chiudere. La stringa pu@`o essere +scritta indifferentemente in maiuscolo o in minuscolo. +@xref{I/O bidirezionale}, +che tratta questa funzionalit@`a con maggior dettaglio e mostra un esempio. + +Si noti che il secondo argomento di @code{close()} @`e +un'estensione @command{gawk}; non @`e disponibile in modalit@`a compatibile +(@pxref{Opzioni}). + +@item @code{fflush(}[@var{nome_file}]@code{)} +@cindexawkfunc{fflush} +@cindex scrivere su disco i buffer di output contenuti in memoria +Scrive su disco ogni output contenuto in memoria, associato con +@var{nome_file}, che @`e o un +file aperto in scrittura o un comando della shell che ridirige output a +una @dfn{pipe} o a un coprocesso. + +@cindex buffer, scrivere su disco un +@cindex memoria tampone, scrivere su disco +@cindex output, bufferizzazione +@cindex output, nella memoria tampone (buffer) +Molti programmi di utilit@`a @dfn{bufferizzano} il loro output (cio@`e, +accumulano in memoria record da scrivere in un file su disco o sullo +schermo, fin quando non arriva il momento giusto per inviare i +dati al dispositivo di output). +Questo @`e spesso pi@`u efficiente che scrivere +ogni particella di informazione non appena diventa disponibile. Tuttavia, +qualche volta @`e necessario forzare un programma a @dfn{svuotare} +i suoi buffer (cio@`e, inviare l'informazione alla sua destinazione, +anche se un buffer non @`e pieno). +Questo @`e lo scopo della funzione @code{fflush()}; anche +@command{gawk} scrive il suo output in un buffer, e la funzione @code{fflush()} +forza @command{gawk} a svuotare i suoi buffer. + +@cindex estensioni comuni, funzione @code{fflush()} +@cindex Brian Kernighan, @command{awk} di +Brian Kernighan ha aggiunto @code{fflush()} al suo @command{awk} nell'aprile +1992. Per due decenni @`e rimasta un'estensione comune. A Dicembre +2012 @`e stata accettata e inclusa nello standard POSIX. +Si veda @uref{http://austingroupbugs.net/view.php?id=634, il sito Web dell'Austin Group}. + +POSIX standardizza @code{fflush()} come segue: se non c'@`e alcun +argomento, o se l'argomento @`e la stringa nulla (@w{@code{""}}), +@command{awk} svuota i buffer di @emph{tutti} i file in output e di +@emph{tutte} le @dfn{pipe}. + +@quotation NOTA +Prima della @value{PVERSION} 4.0.2, @command{gawk} +avrebbe svuotato solo i buffer dello standard output se non era +specificato alcun argomento, +e svuotato tutti i buffer dei file in output e delle @dfn{pipe} se +l'argomento era la stringa nulla. +Questo @`e stato modificato per essere compatibile con l'@command{awk} di +Kernighan, nella speranza che standardizzare questa +funzionalit@`a in POSIX sarebbe stato pi@`u agevole (come poi @`e effettivamente +successo). + +Con @command{gawk}, +si pu@`o usare @samp{fflush("/dev/stdout")} se si desidera solo svuotare i +buffer dello standard output. +@end quotation + +@c @cindex automatic warnings +@c @cindex warnings, automatic +@cindex risoluzione di problemi, funzione @code{fflush()} +@cindex problemi, risoluzione di, funzione @code{fflush()} +@code{fflush()} restituisce zero se il buffer @`e svuotato con successo; +altrimenti, restituisce un valore diverso da zero. (@command{gawk} +restituisce @minus{}1.) +Nel caso in cui tutti i buffer vadano svuotati, il valore restituito @`e zero +solo se tutti i buffer sono stati svuotati con successo. Altrimenti, +@`e @minus{}1, e @command{gawk} avvisa riguardo al @var{nome_file} +che ha problemi. + +@command{gawk} invia anche un messaggio di avvertimento se si tenta di svuotare i +buffer di un file o @dfn{pipe} che era stato aperto in lettura +(p.es. con @code{getline}), +o se @var{nome_file} non @`e un file, una @dfn{pipe}, o un coprocesso aperto. +in tal caso, @code{fflush()} restituisce ancora @minus{}1. + +@sidebar Bufferizzazione interattiva e non interattiva +@cindex bufferizzazione, interattiva vs.@: non interattiva + +A complicare ulteriormente le cose, i problemi di bufferizzazione possono +peggiorare se il programma eseguito +@`e @dfn{interattivo} (cio@`e, se +comunica con un utente seduto davanti a una tastiera).@footnote{Un programma +@`e interattivo se il suo standard output @`e connesso a un dispositivo +terminale. Ai giorni nostri, questo vuol dire davanti a uno +schermo e a una tastiera.} + +@c Thanks to Walter.Mecky@dresdnerbank.de for this example, and for +@c motivating me to write this section. +I programmi interattivi normalmente @dfn{bufferizzano per riga} il loro +output (cio@`e, scrivono in output una riga alla volta). I programmi +non-interattivi attendono di aver riempito un buffer, il che pu@`o voler dire +anche parecchie righe di output. +Ecco un esempio della differenza: + +@example +$ @kbd{awk '@{ print $1 + $2 @}'} +@kbd{1 1} +@print{} 2 +@kbd{2 3} +@print{} 5 +@kbd{Ctrl-d} +@end example + +@noindent +Ogni riga di output @`e stampata immediatamente. Si confronti questo +comportamente con quello di questo esempio: + +@example +$ @kbd{awk '@{ print $1 + $2 @}' | cat} +@kbd{1 1} +@kbd{2 3} +@kbd{Ctrl-d} +@print{} 2 +@print{} 5 +@end example + +@noindent +In questo caso, nessun output viene stampato finch@'e non @`e stato battuto il +@kbd{Ctrl-d}, perch@'e l'output @`e bufferizzato e inviato tramite +@dfn{pipe} al comando @command{cat} in un colpo solo. +@end sidebar + +@item @code{system(@var{comando})} +@cindexawkfunc{system} +@cindex chiamare comandi di shell +@cindex interagire con altri programmi +Esegue il comando del sistema operativo @var{comando} e quindi +ritorna al programma @command{awk}. +Restituisce il codice ritorno di @var{comando}. + +Per esempio, inserendo il seguente frammento di codice in un programma +@command{awk}: + +@example +END @{ + system("date | mail -s 'awk completato' root") +@} +@end example + +@noindent +all'amministratore di sistema viene inviato un messaggio di posta quando +il programma @command{awk} termina di elaborare l'input e inizia +l'elaborazione da eseguire alla fine dell'input. + +Si noti che la ridirezione di @code{print} o @code{printf} in una +@dfn{pipe} @`e spesso sufficiente per ottenere lo stesso risultato. +Se @`e necessario eseguire parecchi comandi, @`e pi@`u efficiente +stamparli verso una @dfn{pipe} diretta alla shell: + +@example +while (@var{ancora lavoro da fare}) + print @var{comando} | "/bin/sh" +close("/bin/sh") +@end example + +@noindent +@cindex risoluzione di problemi, funzione @code{system()} +@cindex problemi, risoluzione di, funzione @code{system()} +@cindex @option{--sandbox}, opzione, disabilitare la funzione @code{system()} +@cindex opzione @option{--sandbox}, disabilitare la funzione @code{system()} +Tuttavia, nel caso che il programma @command{awk} sia interattivo, +@code{system()} @`e utile per eseguire grossi programmi autonomi, +come ad esempio la shell o un programma di modifica testi. +Alcuni sistemi operativi non consentono di implementare la funzione +@code{system()}. +Richiamare @code{system()} in sistemi in cui non @`e disponibile provoca +un errore fatale. + +@quotation NOTA +Quando si specifica l'opzione @option{--sandbox}, la funzione @code{system()} @`e +disabilitata (@pxref{Opzioni}). +@end quotation + +Nei sistemi aderenti allo standard POSIX, il codice di ritorno di un +comando @`e un numero contenuto in 16 bit. Il valore del codice di ritorno +passato alla funzione C @code{exit()} alla fine del programma @`e contenuto +negli 8 bit di valore pi@`u alto dei 16 bit (la met@`a sinistra) che compongono +il numero. I bit di valore pi@`u basso (la met@`a destra) indicano se il +processo @`e stato terminato da un segnale (bit 7), e, se questo @`e il caso, +il numero del segnale che ha provocato la terminazione (bit 0--6). + +Tradizionalmente, la funzione @code{system()} di @command{awk} si @`e +semplicemente limitata a restituire il valore del codice di ritorno +diviso per 256 (ossia la met@`a sinistra del numero di 16 bit, spostata +a destra). In una situazione normale questo equivale a utilizzare il +codice di ritornodi @code{system()}, ma nel caso in cui il programma sia +stato terminato da un segnale, il valore diventa un numero frazionale a +virgola mobile.@footnote{In uno scambio di messaggi privato il Dr.@: +Kernighan mi ha comunicato che questo modo di procedere @`e probabilmente +errato.} POSIX stabilisce che la chiamata a @code{system()} dall'interno +di @command{awk} dovrebbe restituire l'intero valore a 16 bit. + +@command{gawk} si trova in qualche modo a met@`a strada. +I valori del codice di ritorno sono descritti nella +@ref{table-system-return-values}. + +@float Tabella,table-system-return-values +@caption{Valori codici di ritorno da chiamata a @code{system()}} +@multitable @columnfractions .40 .60 +@headitem Situazione @tab Valore codice di ritorno da @code{system()} +@item @option{--traditional} @tab Valore dalla funzione C @code{system()}/256 +@item @option{--posix} @tab Valore dalla funzione C @code{system()} +@item Uscita normale dal comando @tab Codice di ritorno del comando +@item Terminazione da un segnale @tab 256 + numero segnale "assassino" +@item Terminazione da un segnale con dump memoria @tab 512 + numero segnale "assassino" +@item Qualsiasi tipo di errore @tab @minus{}1 +@end multitable +@end float +@end table + +@sidebar Controllare la bufferizzazione dell'output con @code{system()} +@cindex buffer, scrivere su disco un +@cindex bufferizzazione, dell'input/output +@cindex output, bufferizzazione +@cindex bufferizzazione, dell'output + +La funzione @code{fflush()} consente un controllo esplicito sulla +bufferizzazione dell'output per singoli file e @dfn{pipe}. +Tuttavia, il suo utilizzo non @`e portabile su molte delle meno recenti +implementazioni di @command{awk}. Un metodo alternativo per forzare la +scrittura dell'output @`e una chiamata a +@code{system()} che abbia come argomento la stringa nulla: + +@example +system("") # scrive l'output su disco +@end example + +@noindent +@command{gawk} tratta questo uso della funzione @code{system()} come un +caso speciale, e si guarda bene dall'invocare la shell (o un altro +interprete di comandi) con un comando nullo. +Quindi, con @command{gawk}, questa maniera di procedere non @`e solo utile, +ma @`e anche efficiente. +Questo metodo dovrebbe funzionare anche con +altre implementazioni di @command{awk}, ma non @`e detto che eviti una +invocazione non necessaria della shell. (Altre implementazioni potrebbero +limitarsi a forzare la scrittura del buffer associato con lo +standard output, e non necessariamente di tutto l'output bufferizzato.) + +Avendo in mente le attese di un programmatore, sarebbe sensato che +@code{system()} forzi la scrittura su disco di tutto l'output disponibile. +Il programma seguente: + +@example +BEGIN @{ + print "prima riga stampata" + system("echo system echo") + print "seconda riga stampata" +@} +@end example + +@noindent +deve stampare: + +@example +prima riga stampata +system echo +seconda riga stampata +@end example + +@noindent +e non: + +@example +system echo +prima riga stampata +seconda riga stampata +@end example + +Se @command{awk} non forzasse la scrittura dei suoi buffer prima di +invocare @code{system()}, l'output sarebbe quest'ultimo (quello non voluto). +@end sidebar + +@node Funzioni di tempo +@subsection Funzioni per gestire marcature temporali +@cindex funzioni di tempo + +@cindex marcature temporali +@cindex data e ora, si veda marcature temporali +@cindex @dfn{log} (registro), file di, marcature temporali nei +@cindex registro (@dfn{log}), file di, marcature temporali nel +@cindex file di registro (@dfn{log}), marcature temporali nei +@cindex @command{gawk}, data e ora (marcature temporali) +@cindex POSIX @command{awk}, marcature temporali e +I programmi @command{awk} sono frequentemente usati per elaborare file di +registro [file con estensione .log], che contengono l'informazione sulla data e +l'ora (marcatura temporale) in cui un particolare record @`e stato registrato sul log. +Molti programmi registrano questa informazione nel formato restituito +dalla chiamata di sistema @code{time()}, la quale misura il numero di secondi +trascorsi a partire da una certa data iniziale (Epoca). Nei sistemi aderenti +allo standard POSIX, questo @`e il numero di secondi a partire dal primo gennaio +1970, ora di Greenwich (1970-01-01 00:00:00 UTC), senza includere i secondi +@ifclear FOR_PRINT +@iftex +intercalari.@footnote{@xrefIl{Glossario}, +@end iftex +@ifnottex +intercalari.@footnote{@xref{Glossario}, +@end ifnottex +in particolare le voci ``Epoca'' e ``UTC.''} +@end ifclear +@ifset FOR_PRINT +intercalari. +@end ifset +Tutti i sistemi noti aderenti allo standard POSIX gestiscono le marcature +temporali da 0 fino a +@iftex +@math{2^{31} - 1}, +@end iftex +@ifinfo +2^31 - 1, +@end ifinfo +@ifnottex +@ifnotinfo +2@sup{31} @minus{} 1, +@end ifnotinfo +@end ifnottex +il che @`e sufficiente per rappresentare date e ore fino a inizio 2038 +(2038-01-19 03:14:07 UTC). Molti sistemi supportano una maggiore estensione +di date, compresi dei valori negativi per rappresentare delle date +anteriori all'Epoca. + +@cindex @command{date}, programma di utilit@`a GNU +@cindex programma di utilit@`a @command{date} GNU +@cindex tempo, ottenerlo +Per facilitare l'elaborazione di tali file di registro, e per produrre +dei rapporti utili, @command{gawk} prevede le seguenti funzioni per +lavorare con le marcature temporali. Si tratta di estensioni @command{gawk}; +non sono previste nello standard POSIX.@footnote{Il comando di utilit@`a GNU +@command{date} pu@`o fare anche molte delle cose qui descritte. Pu@`o essere +preferibile usarlo per semplici operazioni relative a data e ora in semplici +script della shell.} Tuttavia, anche versioni recenti di @command{mawk} +(@pxref{Altre versioni}) prevedono queste funzioni. I parametri facoltativi +sono racchiusi tra parentesi quadre ([ ]): + +@c @asis for docbook +@table @asis +@item @code{mktime(@var{specifiche_data}} [@code{, @var{utc-flag}} ]@code{)} +@cindexgawkfunc{mktime} +@cindex generare data e ora +Trasforma @var{specifiche_data} in una marcatura temporale nello stesso formato +restituito da @code{systime()}. @`E simile alla funzione omonima +in ISO C. L'argomento, @var{specifiche_data}, @`e una stringa della forma +@w{@code{"@var{AAAA} @var{MM} @var{GG} @var{HH} @var{MM} @var{SS} [@var{DST}]"}}. +La stringa consiste di sei o sette numeri che rappresentano, +rispettivamente, +l'anno in quattro cifre, il mese da 1 a 12, il giorno del mese +da 1 a 31, l'ora del giorno da 0 a 23, il minuto da 0 a +59, il secondo da 0 a 60,@footnote{Occasionalmente ci sono dei +minuti in un anno con un secondo intercalare, il che spiega perch@'e i +secondi possono arrivare fino a 60.} +e un'indicazione opzionale relativa all'ora legale. + +I valori di questi numeri possono non essere negli intervalli specificati; per +esempio, un'ora di @minus{}1 sta a indicare 1 ora prima di mezzanotte. +Viene adottato il calendario gregoriano con l'origine posta all'anno zero, +con l'anno 0 che viene prima dell'anno 1 e l'anno @minus{}1 che viene prima +dell'anno 0. Se il flag @var{utc-flag} @`e specificato ed @`e diverso da zero +e dalla stringa nulla, si suppone che l'ora sia quella del fuso orario UTC; +altrimenti l'ora @`e considerata essere quella del fuso orario locale. Se +l'indicatore dell'ora legale @`e positivo, si presuppone che l'ora sia quella +legale; se @`e 0, l'ora considerata @`e quella di Greenwich (standard time); se +invece @`e negativo (questo @`e il default), @code{mktime()} tenta di +determinare se @`e in vigore l'ora legale o no, nel momento specificato. + +Se @var{specifiche_data} non contiene elementi in numero sufficiente, o se +la data e ora risultante sono fuori dall'intervallo previsto, +@code{mktime()} restituisce @minus{}1. + +@cindex @command{gawk}, vettore @code{PROCINFO} in +@cindex @code{PROCINFO}, vettore +@cindex vettore @code{PROCINFO} +@item @code{strftime(}[@var{formato} [@code{,} @var{data_e_ora} [@code{,} @var{utc}] ] ]@code{)} +@cindexgawkfunc{strftime} +@cindex formato stringa marcature temporali +@cindex formato stringa data e ora +@cindex data e ora, formato stringa +@cindex marcature temporali, formato stringa +Formatta la data e ora specificata da @var{data_e_ora} in base alle indicazioni +contenute nella stringa @var{formato} e restituisce il risultato. +@`E simile alla funzione omonima in ISO C. +Se @var{utc} @`e presente ed @`e diverso da zero o dalla stringa nulla, +il valore @`e formattato come UTC (Tempo Coordinato Universale, +gi@`a noto come GMT o Tempo Medio di Greenwich). +Altrimenti, il valore @`e formattato per il fuso orario locale. +La stringa @var{data_e_ora} @`e nello stesso formato del valore restituito +dalla funzione @code{systime()}. Se non si specifica l'argomento +@var{data_e_ora}, @command{gawk} usa l'ora del giorno corrente per la +formattazione. +Omettendo l'argomento @var{formato}, @code{strftime()} usa +il valore di @code{PROCINFO["strftime"]} come stringa di formattazione +(@pxref{Variabili predefinite}). +Il valore di default della stringa @`e +@code{@w{"%a %b %e %H:%M:%S %Z %Y"}}. Questa stringa di formattazione +produce lo stesso output del programma di utilit@`a equivalente +@command{date}. +Si pu@`o assegnare un nuovo valore a @code{PROCINFO["strftime"]} per +modificare la formattazione di default; si veda +la lista che segue per le varie direttive di formattazione. + +@item @code{systime()} +@cindexgawkfunc{systime} +@cindex marcature temporali +@cindex data e ora, si veda marcature temporali +@cindex data e ora corrente del sistema +Restituisce l'ora corrente come numero di secondi a partire dall'Epoca +del sistema. Sui sistemi aderenti allo standard POSIX, questo @`e il numero +di secondi trascorsi a partire dal primo gennaio 1970, ora di Greenwich +(1970-01-01 00:00:00 UTC), senza includere i secondi intercalari. +@end table + +La funzione @code{systime()} consente di confrontare una marcatura temporale +in un file di registro con la data e ora correnti. In particolare, @`e facile +determinare quanto tempo prima un particolare record @`e stato registrato. +@`E anche possibile produrre record di registro usando il formato +``secondi a partire dall'Epoca''. + +@cindex conversione di date in marcature temporali +@cindex date, conversione in marcature temporali +@cindex marcature temporali, conversione date nelle +La funzione @code{mktime()} consente di convertire una rappresentazione in +forma testuale di una data e ora in una marcatura temporale. +Questo semplifica i confronti prima/dopo tra differenti date e ore, in +particolare quando si abbia a che fare con date e ore provenienti da una +fonte esterna, come un file di registro. + +La funzione @code{strftime()} permette di trasformare facilmente una marcatura +temporale in un'informazione intelligibile. @`E analoga come tipo alla funzione +@code{sprintf()} (@pxref{Funzioni per stringhe}), nel senso che copia +letteralmente ci@`o che non @`e una specifica di formato nella stringa che viene +restituita, mentre sostituisce i valori di data e ora a seconda delle +specifiche di formato contenute nella stringa @var{formato}. + +@cindex specificatori di formato, funzione @code{strftime()} di (@command{gawk}) +@cindex formato, specificatori di, funzione @code{strftime()} di (@command{gawk}) +Per @code{strftime()} lo standard +1999 ISO C@footnote{Sfortunatamente, +non tutte le funzioni @code{strftime()} dei vari sistemi operativi +ammettono tutte le conversioni qui elencate.} +consente le seguenti specifiche di formattazione delle date: + +@table @code +@item %a +Il nome abbreviato del giorno della settimana nella lingua locale. + +@item %A +Il nome completo del giorno della settimana nella lingua locale. + +@item %b +Il nome abbreviato del mese dell'anno nella lingua locale. + +@item %B +Il nome completo del mese dell'anno nella lingua locale. + +@item %c +Il formato ``appropriato'' della rappresentazione della data e ora +nella lingua locale. +(Questo @`e @samp{%A %B %d %T %Y} per la localizzazione @code{"C"}.) + +@item %C +La parte che designa il secolo nell'anno corrente. +Si ottiene dividendo per 100 l'anno, e +troncando verso il basso +all'intero pi@`u vicino. + +@item %d +Il giorno del mese come numero decimale (01--31). + +@item %D +Equivale a specificare @samp{%m/%d/%y}. + +@item %e +Il giorno del mese, preceduto da uno spazio se di tratta di una cifra sola. + +@item %F +Equivale a specificare @samp{%Y-%m-%d}. +Questo @`e il formato ISO 8601 della data. + +@item %g +L'anno (ultime due cifre) ricavato prendendo il resto della divisione per 100 +dell'anno a cui appartiene la settimana, secondo ISO 8601, come numero decimale +(00--99). Per esempio, il primo gennaio 2012, fa parte della settimana 53 del +2011. Quindi, l'anno relativo al numero di settimana ISO di quella data @`e 2011 +(ossia 11), anche se la data in s@'e @`e nel 2012. Analogamente, il 31 dicembre +2012, @`e nella prima settimana del 2013. Quindi, l'anno relativo al numero di +settimana ISO di quella data @`e 2013 (ossia 13), anche se la data in s@'e @`e nel +2012. + +@item %G +L'anno intero relativo al numero di settimana ISO, come numero decimale. + +@item %h +Equivalente a @samp{%b}. + +@item %H +L'ora (in un orologio a 24 ore) come numero decimale (00--23). + +@item %I +L'ora (in un orologio a 12 ore) come numero decimale (01--12). + +@item %j +Il giorno dell'anno come numero decimale (001--366). + +@item %m +Il mese come numero decimale (01--12). + +@item %M +Il minuto come numero decimale (00--59). + +@item %n +Un carattere di ritorno a capo (ASCII LF). + +@item %p +L'equivalente nella lingua locale delle designazioni AM/PM +(mattino/pomerigggio) associate a un orologio a 12 ore. + +@item %r +L'ora locale nel formato a 12 ore. +(Questo @`e @samp{%I:%M:%S %p} nella localizzazione @code{"C"}.) + +@item %R +Equivalente a specificare @samp{%H:%M}. + +@item %S +Il secondo come numero decimale (00--60). + +@item %t +Un carattere di tabulazione [TAB]. + +@item %T +Equivalente a specificare @samp{%H:%M:%S}. + +@item %u +Il numero del giorno della settimana come numero decimale (1--7). +Luned@`{@dotless{i}} @`e il giorno numero 1. + +@item %U +Il numero di settimana dell'anno (con la prima domenica dell'anno presa +come primo giorno della prima settimana) come numero decimale (00--53). + +@c @cindex ISO 8601 +@item %V +Il numero di settimana dell'anno (con il primo luned@`{@dotless{i}} dell'anno preso +come primo giorno della prima settimana) come numero decimale (01--53). +Il metodo per determinare il numero di settimana @`e quello specificato +dallo standard ISO 8601. +(In pratica: se la settimana che contiene il primo gennaio ha quattro o +pi@`u giorni nel nuovo anno, allora +@`e la settimana numero uno; altrimenti @`e l'ultima settimana +[52 o 53] dell'anno +precedente, e la settimana successiva @`e la settimana numero uno.) + +@item %w +Il giorno della settimana come numero decimale (0--6). +Domenica @`e il giorno zero. + +@item %W +Il numero di settimana dell'anno (con il primo luned@`{@dotless{i}} come primo giorno +della settimana numero uno) +come numero decimale (00--53). + +@item %x +Il formato ``appropriato'' della rappresentazione della data +nella lingua locale. +(Questo @`e @samp{%A %B %d %Y} nella localizzazione @code{"C"}.) + +@item %X +Il formato ``appropriato'' della rappresentazione della data. +(Questo @`e @samp{%T} nella localizzazione @code{"C"}.) + +@item %y +L'anno modulo 100 (le ultime due cifre) come numero decimale (00--99). + +@item %Y +L'anno come numero decimale (p.es., 2015). + +@c @cindex RFC 822 +@c @cindex RFC 1036 +@item %z +La differenza di fuso orario [rispetto all'ora di Greenwich] in formato +@samp{+@var{OOMM}} (p.es., il +formato necessario per produrre intestazioni di data conformi agli standard +RFC 822/RFC 1036). + +@item %Z +Il nome o l'abbreviazione della zona di fuso orario (@dfn{time zone}); se il fuso +orario non @`e determinabile, @`e impostata alla stringa nulla. + +@item %Ec %EC %Ex %EX %Ey %EY %Od %Oe %OH +@itemx %OI %Om %OM %OS %Ou %OU %OV %Ow %OW %Oy +``notazioni alternative'' di specifica +in cui solo la seconda lettera (@samp{%c}, @samp{%C} e cos@`{@dotless{i}} via) @`e +significativa.@footnote{Se questo risulta incomprensibile, non @`e il +caso di preoccuparsi; queste notazioni hanno lo scopo di facilitare +la ``internazionalizzazione'' dei programmi. +Altre funzionalit@`a di internazionalizzazione sono descritte in +@ref{Internazionalizzazione}.} +(Queste facilitano la compatibilit@`a con il programma di utilit@`a +POSIX @command{date}.) + +@item %% +Un singolo carattere @samp{%}. +@end table + +Se uno specificatore di conversione non @`e tra quelli elencati sopra, il +comportamento @`e indefinito.@footnote{Questo @`e perch@'e ISO C lascia +indefinito il comportamento della versione C di @code{strftime()} e +@command{gawk} usa la versione di sistema di @code{strftime()}, +se disponibile. +Tipicamente, lo specificatore di conversione "non previsto" non appare +nella stringa risultante, o appare cos@`{@dotless{i}} come @`e scritto.} + +Per sistemi che non aderiscono completamente agli standard +@command{gawk} utilizza una copia di +@code{strftime()} dalla libreria C di GNU. +Sono disponibili tutte le specifiche di formato sopra elencate. +Se la detta versione @`e +usata per compilare @command{gawk} (@pxref{Installazione}), +sono disponibili anche le seguenti ulteriori specifiche di formato: + +@table @code +@item %k +L'ora (in un orologio a 24 ore) come numero decimale (0--23). +I numeri di una sola cifra sono preceduti da uno spazio bianco. + +@item %l +L'ora (in un orologio a 12 ore) come numero decimale (1--12). +I numeri di una sola cifra sono preceduti da uno spazio bianco. + +@ignore +@item %N +Il nome dell'``Imperatore/Era''. +Equivalente a @samp{%C}. + +@item %o +L'anno dell'``Imperatore/Era''. +Equivalente a @samp{%y}. +@end ignore + +@item %s +L'ora espressa in numero di secondi a partire dall'Epoca. + +@ignore +@item %v +La data in formato VMS (p.es., @samp{20-JUN-1991}). +@end ignore +@end table + +In aggiunta a ci@`o, le notazioni alternative sono riconosciute, ma al +loro posto sono usate quelle normali. + +@cindex @code{date}, programma di utilit@`a POSIX +@cindex programma di utilit@`a POSIX @code{date} +@cindex POSIX @command{awk}, programma di utilit@`a @code{date} e +Il seguente esempio @`e un'implementazione @command{awk} del +programma di utilit@`a POSIX @command{date}. +Normalmente, il programma di utilit@`a @command{date} stampa la +data e l'ora corrente nel formato ben noto. Tuttavia, se si +specifica al comando un argomento che inizia con un @samp{+}, @command{date} +copia i caratteri che non sono specifiche di formato nello standard output +e interpreta l'ora corrente secondo gli specificatori di formato +contenuti nella stringa. Per esempio: + +@example +$ @kbd{date '+Oggi @`e %A, %d %B %Y.'} +@print{} Oggi @`e luned@`{@dotless{i}}, 22 settembre 2014. +@end example + +Ecco la versione @command{gawk} del programma di utilit@`a @command{date}. +@`E all'interno di uno script di shell per gestire l'opzione @option{-u}, +che richiede che @command{date} sia eseguito come se il fuso orario +fosse impostato a UTC: + +@example +#! /bin/sh +# +# date --- simula il comando POSIX 'date' + +case $1 in +-u) TZ=UTC0 # usare UTC + export TZ + shift ;; +esac + +gawk 'BEGIN @{ + formato = PROCINFO["strftime"] + codice_di_ritorno = 0 + + if (ARGC > 2) + codice_di_ritorno = 1 + else if (ARGC == 2) @{ + formato = ARGV[1] + if (formato ~ /^\+/) + formato = substr(formato, 2) # togli il + iniziale + @} + print strftime(formato) + exit codice_di_ritorno +@}' "$@@" +@end example + +@node Funzioni a livello di bit +@subsection Funzioni per operazioni di manipolazione bit +@cindex bit, funzioni per la manipolazione di +@cindex manipolazione di bit, funzioni per la +@cindex funzioni per la manipolazione di bit +@cindex bit, operazioni sui +@cindex AND, operazione sui bit +@cindex OR, operazione sui bit +@cindex XOR, operazione sui bit +@cindex operazioni sui bit +@quotation +@i{Io posso spiegarlo per te, ma non posso capirlo per te.} +@author Anonimo +@end quotation + +Molti linguaggi consentono di eseguire operazioni @dfn{bit a bit} +su due numeri interi. In altre parole, l'operazione @`e eseguita +su ogni successiva coppia di bit presi da ognuno dei due operandi. +Tre operazioni comuni sono AND, OR e XOR bit a bit. +Queste operazioni sono descritte nella @ref{table-bitwise-ops}. + +@c 11/2014: Postprocessing turns the docbook informaltable +@c into a table. Hurray for scripting! +@float Tabella,table-bitwise-ops +@caption{Operazioni a livello di bit} +@ifnottex +@ifnotdocbook +@display +@verbatim + Operatore booleano + | AND | OR | XOR + |---+---+---+---+---+--- +Operandi | 0 | 1 | 0 | 1 | 0 | 1 +----------+---+---+---+---+---+--- + 0 | 0 0 | 0 1 | 0 1 + 1 | 0 1 | 1 1 | 1 0 +@end verbatim +@end display +@end ifnotdocbook +@end ifnottex +@tex +\centerline{ +\vbox{\bigskip % space above the table (about 1 linespace) +% Because we have vertical rules, we can't let TeX insert interline space +% in its usual way. +\offinterlineskip +\halign{\strut\hfil#\quad\hfil % operands + &\vrule#&\quad#\quad % rule, 0 (of and) + &\vrule#&\quad#\quad % rule, 1 (of and) + &\vrule# % rule between and and or + &\quad#\quad % 0 (of or) + &\vrule#&\quad#\quad % rule, 1 (of of) + &\vrule# % rule between or and xor + &\quad#\quad % 0 of xor + &\vrule#&\quad#\quad % rule, 1 of xor + \cr +&\omit&\multispan{11}\hfil\bf Operatore booleano\hfil\cr +\noalign{\smallskip} +& &\multispan3\hfil AND\hfil&&\multispan3\hfil OR\hfil + &&\multispan3\hfil XOR\hfil\cr +\bf Operandi&&0&&1&&0&&1&&0&&1\cr +\noalign{\hrule} +\omit&height 2pt&&\omit&&&&\omit&&&&\omit\cr +\noalign{\hrule height0pt}% without this the rule does not extend; why? +0&&0&\omit&0&&0&\omit&1&&0&\omit&1\cr +1&&0&\omit&1&&1&\omit&1&&1&\omit&0\cr +}}} +@end tex + +@docbook +<informaltable> + +<tgroup cols="7" colsep="1"> +<colspec colname="c1"/> +<colspec colname="c2"/> +<colspec colname="c3"/> +<colspec colname="c4"/> +<colspec colname="c5"/> +<colspec colname="c6"/> +<colspec colname="c7"/> +<spanspec spanname="optitle" namest="c2" nameend="c7" align="center"/> +<spanspec spanname="andspan" namest="c2" nameend="c3" align="center"/> +<spanspec spanname="orspan" namest="c4" nameend="c5" align="center"/> +<spanspec spanname="xorspan" namest="c6" nameend="c7" align="center"/> + +<tbody> +<row> +<entry colsep="0"></entry> +<entry spanname="optitle"><emphasis role="bold">Operatore booleano</emphasis></entry> +</row> + +<row rowsep="1"> +<entry rowsep="0"></entry> +<entry spanname="andspan">AND</entry> +<entry spanname="orspan">OR</entry> +<entry spanname="xorspan">XOR</entry> +</row> + +<row rowsep="1"> +<entry ><emphasis role="bold">Operandi</emphasis></entry> +<entry colsep="0">0</entry> +<entry colsep="1">1</entry> +<entry colsep="0">0</entry> +<entry colsep="1">1</entry> +<entry colsep="0">0</entry> +<entry colsep="1">1</entry> +</row> + +<row> +<entry align="center">0</entry> +<entry colsep="0">0</entry> +<entry>0</entry> +<entry colsep="0">0</entry> +<entry>1</entry> +<entry colsep="0">0</entry> +<entry>1</entry> +</row> + +<row> +<entry align="center">1</entry> +<entry colsep="0">0</entry> +<entry>1</entry> +<entry colsep="0">1</entry> +<entry>1</entry> +<entry colsep="0">1</entry> +<entry>0</entry> +</row> + +</tbody> +</tgroup> +</informaltable> +@end docbook +@end float + +@cindex bit, complemento a livello di +@cindex complemento a livello di bit +Come si vede, il risultato di un'operazione di AND @`e 1 solo quando +@emph{entrambi} i bit sono 1. +Il risultato di un'operazione di OR @`e 1 se @emph{almeno un} bit @`e 1. +Il risultato di un'operazione di XOR @`e 1 se l'uno o l'altro +bit @`e 1, ma non tutti e due. +La successiva operazione @`e il @dfn{complemento}; il complemento di 1 @`e 0 e +il complemento di 0 @`e 1. Quindi, quest'operazione ``inverte'' tutti i bit +di un dato valore. + +@cindex bit, spostamento di +@cindex spostamento a sinistra, bit a bit +@cindex spostamento a destra, bit a bit +@cindex spostamento, bit a bit +Infine, due altre operazioni comuni consistono nello spostare i bit +a sinistra o a destra. +Per esempio, se si ha una stringa di bit @samp{10111001} e la si sposta +a destra di tre bit, si ottiene @samp{00010111}.@footnote{Questo esempio +presuppone che degli zeri riempiano le posizioni a sinistra. +Per @command{gawk}, @`e sempre +cos@`{@dotless{i}}, ma in alcuni linguaggi @`e possibile che le posizioni a sinistra +siano riempite con degli uno.} +Partendo nuovamente da @samp{10111001} e spostandolo a sinistra di tre +bit, si ottiene @samp{11001000}. La lista seguente descrive +le funzioni predefinite di @command{gawk} che rendono disponibili +le operazioni a livello di bit. +I parametri facoltativi sono racchiusi tra parentesi quadre ([ ]): + +@cindex @command{gawk}, operazioni a livello di bit in +@table @code +@cindexgawkfunc{and} +@cindex AND, operazione sui bit +@item @code{and(}@var{v1}@code{,} @var{v2} [@code{,} @dots{}]@code{)} +Restituisce l'AND bit a bit degli argomenti. +Gli argomenti devono essere almeno due. + +@cindexgawkfunc{compl} +@cindex complemento a livello di bit +@item @code{compl(@var{val})} +Restituisce il complemento bit a bit di @var{val}. + +@cindexgawkfunc{lshift} +@cindex spostamento a sinistra +@item @code{lshift(@var{val}, @var{contatore})} +Restituisce il valore di @var{val}, spostato a sinistra di +@var{contatore} bit. + +@cindexgawkfunc{or} +@cindex OR, operazione sui bit +@item @code{or(}@var{v1}@code{,} @var{v2} [@code{,} @dots{}]@code{)} +Restituisce l'OR bit a bit degli argomenti. +Gli argomenti devono essere almeno due. + +@cindexgawkfunc{rshift} +@cindex spostamento a destra +@item @code{rshift(@var{val}, @var{contatore})} +Restituisce il valore di @var{val}, spostato a destra +di @var{contatore} bit. + +@cindexgawkfunc{xor} +@cindex XOR, operazione sui bit +@item @code{xor(}@var{v1}@code{,} @var{v2} [@code{,} @dots{}]@code{)} +Restituisce il XOR bit a bit degli argomenti. +Gli argomenti devono essere almeno due. +@end table + +@quotation ATTENZIONE +A partire dalla versione di @command{gawk} @value{PVERSION} 4.2, gli operandi +negativi non sono consentiti per nessuna di queste funzioni. Un operando +negativo produce un errore fatale. Si veda la nota a lato +``Attenzione. Non @`e tutto oro quel che luccica!'' per maggiori informazioni sul perch@'e. +@end quotation + +Ecco una funzione definita dall'utente (@pxref{Funzioni definite dall'utente}) +che illustra l'uso di queste funzioni: + +@cindex @code{bits2str()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{bits2str()} +@cindex @code{testbits.awk}, programma +@cindex programma @code{testbits.awk} +@example +@group +@c file eg/lib/bits2str.awk +# bits2str --- decodifica un byte in una serie di 0/1 leggibili + +function bits2str(byte, dati, maschera) +@{ + if (byte == 0) + return "0" + + maschera = 1 + for (; byte != 0; stringa = rshift(stringa, 1)) + dati = (and(byte, maschera) ? "1" : "0") dati + + while ((length(dati) % 8) != 0) + dati = "0" dati + + return dati +@} +@c endfile +@end group + +@c this is a hack to make testbits.awk self-contained +@ignore +@c file eg/prog/testbits.awk +# bits2str --- turn a byte into readable 1's and 0's + +function bits2str(bits, data, mask) +@{ + if (bits == 0) + return "0" + + mask = 1 + for (; bits != 0; bits = rshift(bits, 1)) + data = (and(bits, mask) ? "1" : "0") data + + while ((length(data) % 8) != 0) + data = "0" data + + return data +@} +@c endfile +@end ignore +@c file eg/prog/testbits.awk +BEGIN @{ + printf "123 = %s\n", bits2str(123) + printf "0123 = %s\n", bits2str(0123) + printf "0x99 = %s\n", bits2str(0x99) + comp = compl(0x99) + printf "compl(0x99) = %#x = %s\n", comp, bits2str(comp) + shift = lshift(0x99, 2) + printf "lshift(0x99, 2) = %#x = %s\n", shift, bits2str(shift) + shift = rshift(0x99, 2) + printf "rshift(0x99, 2) = %#x = %s\n", shift, bits2str(shift) +@} +@c endfile +@end example + +@noindent +Questo programma produce il seguente output quando viene eseguito: + +@example +$ @kbd{gawk -f testbits.awk} +@print{} 123 = 01111011 +@print{} 0123 = 01010011 +@print{} 0x99 = 10011001 +@print{} compl(0x99) = 0x3fffffffffff66 = 001111111111111111111111111111111 +@print{} 11111111111111101100110 +@print{} lshift(0x99, 2) = 0x264 = 0000001001100100 +@print{} rshift(0x99, 2) = 0x26 = 00100110 +@end example + +@cindex conversione da stringhe a numeri +@cindex stringhe, conversione +@cindex numeri, conversione in stringhe +@cindex conversione da numeri a stringhe +@cindex numero visto come stringa di bit +La funzione @code{bits2str()} trasforma un numero binario in una stringa. +Inizializzando @code{maschera} a uno otteniamo +un valore binario in cui il bit pi@`u a destra @`e impostato a +uno. Usando questa maschera, +la funzione continua a controllare il bit pi@`u a destra. +l'operazione di AND tra la maschera e il valore indica se il +bit pi@`u a destra @`e uno oppure no. Se questo @`e il caso, un @code{"1"} +@`e concatenato all'inizio della stringa. +Altrimenti, @`e concatenato uno @code{"0"}. +Il valore @`e quindi spostato a destra di un bit e il ciclo continua +finch@'e non ci sono pi@`u bit. + +Se il valore iniziale @`e zero, viene restituito semplicemente uno @code{"0"}. +Altrimenti, alla fine, al valore ottenuto vengono aggiunti degli zeri a +sinistra, per arrivare a stringhe +di lunghezza multipla di 8, ossia contenenti un numero intero di byte. +Questo @`e tipico dei computer moderni. + +Il codice principale nella regola @code{BEGIN} mostra la differenza tra +i valori decimale e ottale dello stesso numero. +(@pxref{Numeri non-decimali}), +e poi mostra i risultati delle funzioni +@code{compl()}, @code{lshift()} e @code{rshift()}. + +@sidebar Attenzione. Non @`e tutto oro quel che luccica! + +In altri linguaggi, le operazioni "bit a bit" sono eseguite su valori interi, +non su valori a virgola mobile. Come regola generale, tali operazioni +funzionano meglio se eseguite su interi senza segno. + +@command{gawk} tenta di trattare gli argomenti delle funzioni +"bit a bit" come interi senza segno. Per questo motivo, gli argomenti negativi +provocano un errore fatale. + +In una normale operazione, per tutte queste funzioni, prima il valore a virgola +mobile a doppia precisione viene convertito nel tipo intero senza segno di C +pi@`u ampio, poi viene eseguita l'operazione "bit a bit". Se il risultato non +pu@`o essere rappresentato esattamente come un tipo @code{double} di C, +vengono rimossi i bit iniziali diversi da zero uno alla volta finch@'e +non sono rappresentati esattamente. Il risultato @`e poi nuovamente convertito +in un tipo @code{double} di C.@footnote{Per essere pi@`u chiari, +la conseguenza @`e che @command{gawk} pu@`o memorizzare solo un determinato +intervallo di valori interi; i numeri al di fuori di questo intervallo vengono +ridotti per rientrare all'interno dell'intervallo.} + +Comunque, quando si usa il calcolo con precisione arbitraria con l'opzione +@option{-M} (@pxref{Calcolo con precisione arbitraria}), il risultato pu@`o +essere diverso. Questo @`e particolarmente evidente con la funzione @code{compl()}: + +@example +$ @kbd{gawk 'BEGIN @{ print compl(42) @}'} +@print{} 9007199254740949 +$ @kbd{gawk -M 'BEGIN @{ print compl(42) @}'} +@print{} -43 +@end example + +Quel che avviene diventa chiaro quando si stampano i risultati +in notazione esadecimale: + +@example +$ @kbd{gawk 'BEGIN @{ printf "%#x\n", compl(42) @}'} +@print{} 0x1fffffffffffd5 +$ @kbd{gawk -M 'BEGIN @{ printf "%#x\n", compl(42) @}'} +@print{} 0xffffffffffffffd5 +@end example + +Quando si usa l'opzione @option{-M}, nel dettaglio, @command{gawk} usa +gli interi a precisione arbitraria di GNU MP che hanno almeno 64 bit di precisione. +Quando non si usa l'opzione @option{-M}, @command{gawk} memorizza i valori +interi come regolari valori a virgola mobile con doppia precisione, che +mantengono solo 53 bit di precisione. Inoltre, la libreria GNU MP tratta +(o almeno sembra che tratti) il bit iniziale come un bit con segno; cos@`i il +risultato con @option{-M} in questo caso @`e un numero negativo. + +In breve, usare @command{gawk} per qualsiasi tipo di operazione "bit a bit", +tranne le pi@`u semplici, probabilmente @`e una cattiva idea; caveat emptor! + +@end sidebar + +@node Funzioni per i tipi +@subsection Funzioni per conoscere il tipo di una variabile + +@command{gawk} prevede due funzioni che permettono di conoscere +il tipo di una variabile. +Questo @`e necessario per scrivere del codice che visiti ogni elemento di un +vettore di vettori +(@pxref{Vettori di vettori}) e in altri contesti. + +@table @code +@cindexgawkfunc{isarray} +@cindex scalare o vettore +@item isarray(@var{x}) +Restituisce il valore 'vero' se @var{x} @`e un vettore. Altrimenti, restituisce +'falso'. + +@cindexgawkfunc{typeof} +@cindex variabile, tipo di una +@cindex tipo di una variabile +@item typeof(@var{x}) +Restituisce una delle stringhe seguenti, a seconda del tipo di @var{x}: + +@c nested table +@table @code +@item "array" +@var{x} @`e un vettore. + +@item "regexp" +@var{x} @`e una @dfn{regexp} fortemente tipizzata +(@pxref{Costanti @dfn{regexp} forti}). + +@item "number" +@var{x} @`e un numero. + +@item "string" +@var{x} @`e una stringa. + +@item "strnum" +@var{x} @`e un numero che ha avuto origine da un input dell'utente, +come un campo o il risultato di una chiamata a @code{split()}. +(Cio@`e, @var{x} ha l'attributo @dfn{strnum}; +@pxref{Tipi di variabile}.) + +@item "unassigned" +@var{x} @`e una variabile scalare a cui non @`e ancora stato assegnato un valore. +Per esempio: + +@example +BEGIN @{ + # crea a[1] ma non gli attribuisce alcun valore + a[1] + print typeof(a[1]) # unassigned +@} +@end example + +@item "untyped" +@var{x} non @`e stata usata per nulla; pu@`o diventare uno scalare o un +vettore. +Per esempio: + +@example +BEGIN @{ + print typeof(x) # x non @`e mai stato usato --> untyped + mk_arr(x) + print typeof(x) # x ora @`e un vettore --> array +@} + +function mk_arr(a) @{ a[1] = 1 @} +@end example + +@end table +@end table + +@code{isarray()} torna utile in due occasioni. La prima @`e quando +si visita un vettore multidimensionale: si pu@`o stabilire se un elemento @`e +un vettore oppure no. La seconda @`e all'interno del corpo di una funzione +definita dall'utente (argomento non ancora trattato; +@pxref{Funzioni definite dall'utente}), per determinare se un parametro +@`e un vettore oppure no. + +@quotation NOTA +Usare @code{isarray()} a livello globale per controllare le variabili +non ha alcun senso. Si suppone infatti che chi scrive il programma +sappia se una variabile @`e un vettore oppure no. E in +effetti, per come funziona @command{gawk}, se si passa una variabile +che non sia stata usata in precedenza a @code{isarray()}, @command{gawk} +la crea al volo, assegnandole il tipo scalare. +@end quotation + +La funzione @code{typeof()} @`e generale; consente di determinare +se una variabile o un parametro di funzione @`e uno scalare, un vettore, +o una @dfn{regexp} fortemente tipizzata. + +L'uso di @code{isarray()} @`e deprecato; si dovrebbe usare @code{typeof()} +al suo posto. Si dovrebbe sostituire ogni uso esistente di +@samp{isarray(var)} nei programmi esistenti con +@samp{typeof(var) == "array"}. + +@node Funzioni di internazionalizzazione +@subsection Funzioni per tradurre stringhe +@cindex @command{gawk}, funzioni di traduzione di stringhe +@cindex funzioni di traduzione di stringhe +@cindex traduzione di stringhe, funzioni di +@cindex internazionalizzazione +@cindex programmi @command{awk}, internazionalizzare + +@command{gawk} prevede strumenti per internazionalizzare i programmi +@command{awk}. +Questi sono costituiti dalle funzioni descritte nella lista seguente. +Le descrizioni sono volutamente concise. +@xref{Internazionalizzazione}, +per un'esposizione completa. +I parametri facoltativi sono racchiusi tra parentesi quadre ([ ]): + +@table @asis +@cindexgawkfunc{bindtextdomain} +@cindex impostare directory con catalogo messaggi tradotti +@cindex messaggi tradotti, impostare directory con catalogo +@item @code{bindtextdomain(@var{directory}} [@code{,} @var{dominio}]@code{)} +Imposta la directory in cui +@command{gawk} trova i file di traduzione dei messaggi, nel caso in cui +non siano o non possano essere messi nelle directory ``standard'' +(p.es., durante la fase di test di un programma). +Restituisce la directory alla quale @var{dominio} @`e ``connesso.'' + +Il default per @var{dominio} @`e il valore di @code{TEXTDOMAIN}. +Se @var{directory} @`e la stringa nulla (@code{""}), +@code{bindtextdomain()} restituisce la connessione corrente per il +@var{dominio} dato. + +@cindexgawkfunc{dcgettext} +@cindex traduzione di stringhe +@item @code{dcgettext(@var{stringa}} [@code{,} @var{dominio} [@code{,} @var{categoria}] ]@code{)} +Restituisce la traduzione di @var{stringa} nel +dominio linguistico @var{dominio} per la categoria di localizzazione +@var{categoria}. +Il valore di default per @var{dominio} @`e il valore corrente di @code{TEXTDOMAIN}. +Il valore di default per @var{categoria} @`e @code{"LC_MESSAGES"}. + +@cindexgawkfunc{dcngettext} +@item @code{dcngettext(@var{stringa1}, @var{stringa2}, @var{numero}} [@code{,} @var{dominio} [@code{,} @var{categoria}] ]@code{)} +Restituisce la forma plurale usata per @var{numero} nella +traduzione di @var{stringa1} e @var{stringa2} nel dominio di testo +@var{dominio} per la categoria di localizzazione @var{categoria}. +@var{stringa1} @`e la variante al singolare in inglese di un messaggio e +@var{stringa2} @`e la variante al plurare in inglese dello stesso messaggio. +Il valore di default per @var{dominio} @`e il valore corrente di @code{TEXTDOMAIN}. +Il valore di default per @var{categoria} @`e @code{"LC_MESSAGES"}. +@end table + +@node Funzioni definite dall'utente +@section Funzioni definite dall'utente + +@cindex funzioni definite dall'utente +@cindex utente, funzioni definite dall' +Programmi @command{awk} complessi spesso possono essere semplificati +definendo delle apposite funzioni personali. +Le funzioni definite dall'utente sono richiamate allo stesso modo di quelle +predefinite +(@pxref{Chiamate di funzione}), +ma dipende dall'utente la loro definizione +(cio@`e, dire ad @command{awk} cosa dovrebbero fare queste funzioni). + +@menu +* Sintassi delle definizioni:: Come scrivere definizioni e cosa + significano. +* Esempio di funzione:: Un esempio di definizione di + funzione e spiegazione della stessa. +* Precisazioni sulle funzioni:: Cose a cui prestare attenzione. +* Istruzione return:: Specificare il valore che una + funzione restituisce. +* Variabili di tipo dinamico:: Come cambiare tipo a una variabile in + fase di esecuzione del programma. +@end menu + +@node Sintassi delle definizioni +@subsection Come scrivere definizioni e cosa significano + +@quotation +@i{Risponde al vero affermare che la sintassi di awk per la definizione +di variabili locali @`e semplicemente atroce.} +@author Brian Kernighan +@end quotation + +@cindex funzioni, definizione di +@cindex definizione di funzioni +Definizioni di funzioni possono stare in una posizione qualsiasi tra le regole +di un programma @command{awk}. Quindi, la forma generale di un +programma @command{awk} @`e estesa per +permettere l'inclusione di regole @emph{e} la definizione di funzioni +create dall'utente. +Non @`e necessario che la definizione di una funzione sia posta prima +del richiamo della stessa. Questo dipende dal fatto che @command{awk} +legge l'intero programma, prima di iniziare ad eseguirlo. + +La definizione di una funzione chiamata @var{nome} @`e simile a questa: + +@display +@code{function} @var{nome}@code{(}[@var{lista-parametri}]@code{)} +@code{@{} + @var{corpo-della-funzione} +@code{@}} +@end display + +@cindex nomi di funzione +@cindex funzioni, nomi di +@cindex limitazioni nei nomi di funzione +@cindex nomi di funzione, limitazioni nei +@noindent +Qui, @var{nome} @`e il nome della funzione da definire. Un nome di funzione +valido @`e come un nome di variabile valido: una sequenza di +lettere, cifre e trattini bassi che non inizia con una cifra. +Anche qui, solo le 52 lettere inglesi maiuscole e minuscole possono +essere usate in un nome di funzione. +All'interno di un singolo programma @command{awk}, un dato nome pu@`o essere +usato una sola volta: per una variabile, o per un vettore, +o per una funzione. + +@var{lista-parametri} @`e una lista opzionale degli argomenti della funzione +e dei nomi delle variabili locali, +separati da virgole. Quando la funzione viene chiamata, +i nomi degli argomenti sono usati per contenere il valore degli argomenti +passati con la chiamata. + +Una funzione non pu@`o avere due parametri con lo stesso nome, e neanche un +parametro con lo stesso nome della funzione stessa. + +@quotation ATTENZIONE +Secondo lo standard POSIX, i parametri di funzione +non possono avere lo stesso nome di una delle speciali variabili predefinite +(@pxref{Variabili predefinite}), e un parametro di funzione non pu@`o avere +lo stesso nome di un'altra funzione. +Non tutte le versioni di @command{awk} applicano queste limitazioni. +@command{gawk} applica solo la prima di queste restrizioni. +Se viene specificata l'opzione @option{--posix} (@pxref{Opzioni}), +anche la seconda restrizione viene applicata. +@end quotation + +Le variabili locali si comportano come la stringa vuota +se vengono utilizzate dove @`e richiesto il valore di una stringa, +e valgono zero se utilizzate dove @`e richiesto un valore numerico. +Questo @`e lo stesso comportamento delle variabili regolari a cui non sia +stato ancora assegnato un valore. (Ci sono ulteriori informazioni riguardo +alle variabili locali; +@pxref{Variabili di tipo dinamico}.) + +Il @var{corpo-della-funzione} @`e composto da istruzioni @command{awk}. +Questa @`e la parte pi@`u importante della definizione, perch@'e dice quello che +la funzione dovrebbe realmente +@emph{fare}. I nomi di argomento esistono per consentire al corpo della +funzione di gestire gli argomenti; +le variabili locali esistono per consentire al corpo della funzione di +memorizzare dei valori temporanei. + +I nomi di argomento non sono sintatticamente distinti da quelli delle +variabili locali. Invece, il numero di argomenti forniti quando la +funzione viene chiamata determina quanti degli argomenti passati sono delle +variabili. Quindi, se tre valori di argomento sono specificati, i primi +tre nomi in @var{lista-parametri} +sono degli argomenti e i rimanenti sono delle variabili locali. + +Ne consegue che se il numero di argomenti richiesto non @`e lo stesso in +tutte le chiamate alla funzione, alcuni dei nomi in @var{lista-parametri} +possono essere in alcuni casi degli argomenti e in altri casi +delle variabili locali. Un'altra angolatura da cui guardare questo fatto +@`e che gli argomenti omessi assumono come valore di default la stringa nulla. + +@cindex convenzioni di programmazione, nella scrittura di funzioni +@cindex funzioni, convenzioni di programmazione, nella scrittura di +Solitamente, quando si scrive una funzione, si sa quanti nomi si intendono +usare per gli argomenti e quanti si vogliono usare come variabili locali. +@`E una convenzione in uso quella di aggiungere alcuni spazi extra tra gli +argomenti e le variabili locali, per documentare come va utilizzata quella +funzione. + +@cindex variabili nascoste +@cindex nascondere valori di variabile +Durante l'esecuzione del corpo della funzione, gli argomenti e i valori +delle variabili locali +nascondono, o @dfn{oscurano}, qualsiasi variabile dello stesso nome usata +nel resto del programma. Le variabili oscurate non sono accessibili +nel corpo della funzione, perch@'e non c'@`e modo di accedere a esse +mentre i loro nomi sono stati "occupati" dagli argomenti e dalla variabili +locali. Tutte le altre variabili usate nel programma @command{awk} +possono essere accedute o impostate normalmente nel corpo della funzione. + +Gli argomenti e le variabili locali esistono solo finch@'e il corpo della +funzione @`e in esecuzione. Una volta che l'esecuzione @`e terminata, +ritornano accessibili le variabili che erano oscurate +durante l'esecuzione della funzione. + +@cindex ricorsive, funzioni +@cindex funzioni ricorsive +Il corpo della funzione pu@`o contenere espressioni che chiamano altre +funzioni. Tali espressioni possono perfino chiamare direttamente, o +indirettamente tramite un'altra funzione, la funzione stessa. +Quando questo succede, la funzione @`e detta @dfn{ricorsiva}. +Il fatto che una funzione richiami se stessa @`e detto @dfn{ricorsione}. + +Tutte le funzioni predefinite restituiscono un valore al loro chiamante. +Anche le funzioni definite dall'utente possono farlo, usando +l'istruzione @code{return}, +che @`e descritta in dettaglio nella @ref{Istruzione return}. +Molti dei successivi esempi in questa @value{SECTION} usano +l'istruzione @code{return}. + +@cindex estensioni comuni, parola chiave @code{func} +@c @cindex @command{awk} language, POSIX version +@c @cindex POSIX @command{awk} +@cindex POSIX @command{awk}, parola chiave @code{function} in +In molte implementazioni di @command{awk}, compreso @command{gawk}, +la parola chiave @code{function} pu@`o essere +abbreviata come @code{func}. @value{COMMONEXT} +Tuttavia, POSIX specifica solo l'uso della parola chiave +@code{function}. Questo ha alcune implicazioni di carattere pratico. +Se @command{gawk} @`e in modalit@`a POSIX-compatibile +(@pxref{Opzioni}), la seguente +istruzione @emph{non} definisce una funzione: + +@example +func foo() @{ a = sqrt($1) ; print a @} +@end example + +@noindent +Invece, definisce una regola che, per ogni record, concatena il valore +della variabile @samp{func} con il valore restituito dalla funzione @samp{foo}. +Se la stringa risultante @`e diversa dalla stringa nulla, l'azione viene eseguita. +Questo non @`e con ogni probabilit@`a quello che si desidera. +(@command{awk} accetta questo input come +sintatticamente valido, perch@'e le funzioni, nei programmi @command{awk} +possono essere usate prima che siano state definite.@footnote{Questo +programma in realt@`a non verr@`a eseguito, perch@'e @code{foo()} risulter@`a +essere una funzione non definita.}) + +@cindex portabilit@`a, nella definizione di funzioni +Per essere certi che un programma @command{awk} sia portabile, +va sempre usata la parola chiave +@code{function} per definire una funzione. + +@node Esempio di funzione +@subsection Un esempio di definizione di funzione +@cindex esempio di definizione di funzione +@cindex funzione, esempio di definizione di + + +Ecco un esempio di funzione definita dall'utente, di nome +@code{stampa_num()}, che +ha come input un numero e lo stampa in un formato specifico: + +@example +function stampa_num(numero) +@{ + printf "%6.3g\n", numero +@} +@end example + +@noindent +Per comprenderne il funzionamento, ecco una regola @command{awk} che usa +la funzione @code{stampa_num()}: + +@example +$3 > 0 @{ stampa_num($3) @} +@end example + +@noindent +Questo programma stampa, nel nostro formato speciale, tutti i terzi campi +nei record in input che +contengono un numero positivo. Quindi, dato il seguente input: + +@example + 1.2 3.4 5.6 7.8 + 9.10 11.12 -13.14 15.16 +17.18 19.20 21.22 23.24 +@end example + +@noindent +questo programma, usando la nostra funzione per formattare i risultati, stampa: + +@example + 5.6 + 21.2 +@end example + +La funzione seguente cancella tutti gli elementi in un vettore +(si ricordi che gli spazi bianchi in soprannumero stanno a indicare +l'inizio della lista delle variabili locali): + +@example +function cancella_vettore(a, i) +@{ + for (i in a) + delete a[i] +@} +@end example + +Quando si lavora con vettori, @`e spesso necessario cancellare +tutti gli elementi in un vettore e ripartire con una nuova lista di elementi +(@pxref{Cancellazione}). +Invece di dover ripetere +questo ciclo ogni volta che si deve cancellare +un vettore, un programma pu@`o limitarsi a effettuare una chiamata +a @code{cancella_vettore()}. +(Questo garantisce la portabilit@`a. L'uso di @samp{delete @var{vettore}} +per cancellare +il contenuto di un intero vettore @`e un'aggiunta relativamente +recente@footnote{Verso la fine del 2012.} +allo standard POSIX.) + +Quello che segue @`e un esempio di una funzione ricorsiva. Prende come +parametro di input una stringa e restituisce la stringa in ordine inverso. +Le funzioni ricorsive devono sempre avere un test che interrompa la +ricorsione. +In questo caso, la ricorsione termina quando la stringa in input @`e +gi@`a vuota: + +@c 8/2014: Thanks to Mike Brennan for the improved formulation +@cindex @code{rev()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{rev()} +@example +function rev(stringa) +@{ + if (stringa == "") + return "" + + return (rev(substr(stringa, 2)) substr(stringa, 1, 1)) +@} +@end example + +Se questa funzione @`e in un file di nome @file{rev.awk}, si pu@`o provare +cos@`{@dotless{i}}: + +@example +$ @kbd{echo "Non v'allarmate!" |} +> @kbd{gawk -e '@{ print rev($0) @}' -f rev.awk} +@print{} !etamralla'v noN +@end example + +La funzione C @code{ctime()} prende una marcatura temporale e la restituisce +come una stringa, +formattata come gi@`a sappiamo. +Il seguente esempio usa la funzione predefinita @code{strftime()} +(@pxref{Funzioni di tempo}) +per creare una versione @command{awk} di @code{ctime()}: + +@cindex @code{ctime()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{ctime()} +@example +@c file eg/lib/ctime.awk +# ctime.awk +# +# versione awk della funzione C ctime(3) + +function ctime(ts, format) +@{ + format = "%a %e %b %Y, %H.%M.%S, %Z" + + if (ts == 0) + ts = systime() # usare data e ora correnti per default + return strftime(format, ts) +@} +@c endfile +@end example + +Si potrebbe pensare che la funzione @code{ctime()} possa usare +@code{PROCINFO["strftime"]} +come stringa di formato. Sarebbe un errore, perch@'e si suppone che +@code{ctime()} restituisca data e ora formattati in maniera standard, +e qualche codice a livello utente potrebbe aver modificato in precedenza +@code{PROCINFO["strftime"]}. + +@node Precisazioni sulle funzioni +@subsection Chiamare funzioni definite dall'utente + +@cindex funzioni definite dall'utente, chiamare +@cindex chiamare funzioni definite dall'utente +@dfn{Chiamare una funzione} significa richiedere l'esecuzione di una +funzione, la quale svolge il compito per cui @`e stata scritta. +La chiamata di una funzione @`e un'espressione e il suo valore @`e quello +restituito dalla funzione. + +@menu +* Chiamare una funzione:: Non usare spazi. +* Campo di validit@`a variabili:: Variabili locali e globali. +* Parametri per valore/riferimento:: Passaggio parametri. +@end menu + +@node Chiamare una funzione +@subsubsection Scrivere una chiamata di funzione + +Una chiamata di funzione consiste nel nome della funzione seguito dagli +argomenti racchiusi tra parentesi. Gli argomenti specificati nella chiamata +sono costituiti da espressioni @command{awk}. Ogni volta che si esegue una +chiamata queste espressioni vengono ricalcolate, e i loro valori diventano gli +argomenti passati alla funzione. Per esempio, ecco una chiamata a +@code{pippo()} con tre argomenti (il primo dei quali @`e una concatenazione di +stringhe): + +@example +pippo(x y, "perdere", 4 * z) +@end example + +@quotation ATTENZIONE +Caratteri bianchi (spazi e TAB) non sono permessi tra il nome della funzione e +la parentesi aperta che apre la lista degli argomenti. Se per errore si +lasciano dei caratteri bianchi, @command{awk} li interpreterebbe come se +s'intendesse concatenare una variabile con un'espressione tra parentesi. +Tuttavia, poich@'e si @`e usato un nome di funzione e non un nome di variabile, +verrebbe emesso un messaggio di errore. +@end quotation + +@node Campo di validit@`a variabili +@subsubsection Variabili locali e globali. + +@cindex variabili locali, in una funzione +@cindex locali, variabili, per una funzione +Diversamente da molti altri linguaggi, non c'@`e modo di +rendere locale una variabile in un blocco @code{@{} @dots{} @code{@}} di +@command{awk}, ma si pu@`o rendere locale una variabile di una funzione. @`E +buona norma farlo quando una variabile serve solo all'interno di quella +particolare funzione. + +Per rendere locale una variabile per una funzione, basta dichiarare la +variabile come argomento della funzione dopo gli argomenti richiesti dalla +funzione (@pxref{Sintassi delle definizioni}). Si consideri il seguente +esempio, dove la variabile @code{i} @`e una variabile globale usata sia dalla +funzione @code{pippo()} che dalla funzione @code{pluto()}: + +@example +function pluto() +@{ + for (i = 0; i < 3; i++) + print "in pluto i=" i +@} + +function pippo(j) +@{ + i = j + 1 + print "in pippo i=" i + pluto() + print "in pippo i=" i +@} + +BEGIN @{ + i = 10 + print "in BEGIN i=" i + pippo(0) + print "in BEGIN i=" i +@} +@end example + +L'esecuzione di questo script produce quanto segue, perch@'e la stessa +variabile @code{i} @`e usata sia nelle +funzioni @code{pippo()} e @code{pluto()} sia a livello della +regola @code{BEGIN}: + +@example +in BEGIN i=10 +in pippo i=1 +in pluto i=0 +in pluto i=1 +in pluto i=2 +in pippo i=3 +in BEGIN i=3 +@end example + +Se si vuole che @code{i} sia una variabile locale sia per +@code{pippo()} che per @code{pluto()}, occorre procedere in questo modo +(gli spazi extra prima della @code{i} sono una convenzione di codifica +che serve a ricordare che @code{i} @`e una variabile locale, non +un argomento): + +@example +function pluto( i) +@{ + for (i = 0; i < 3; i++) + print "in pluto i=" i +@} + +function pippo(j, i) +@{ + i = j + 1 + print "in pippo i=" i + pluto() + print "in pippo i=" i +@} + +BEGIN @{ + i = 10 + print "in BEGIN i=" i + pippo(0) + print "in BEGIN i=" i +@} +@end example + +L'esecuzione della versione corretta dello script produce il seguente +output: + +@example +in BEGIN i=10 +in pippo i=1 +in pluto i=0 +in pluto i=1 +in pluto i=2 +in pippo i=1 +in BEGIN i=10 +@end example + +Oltre a valori scalari (stringhe e numeri), si possono usare anche +vettori locali. Usando come parametro il nome di un vettore, @command{awk} +lo considera come tale, e lo tratta come locale alla funzione. +Inoltre, chiamate ricorsive creano nuovi vettori. +Si consideri questo esempio: + +@example +function qualche_funz(p1, a) +@{ + if (p1++ > 3) + return + + a[p1] = p1 + + qualche_funz(p1) + + printf("Al livello %d, indice %d %s trova in a\n", + p1, (p1 - 1), (p1 - 1) in a ? "si" : "non si") + printf("Al livello %d, indice %d %s trova in a\n", + p1, p1, p1 in a ? "si" : "non si") + print "" +@} + +BEGIN @{ + qualche_funz(1) +@} +@end example + +Quando viene eseguito, questo programma produce il seguente output: + +@example +Al livello 4, indice 3 non si trova in a +Al livello 4, indice 4 si trova in a + +Al livello 3, indice 2 non si trova in a +Al livello 3, indice 3 si trova in a + +Al livello 2, indice 1 non si trova in a +Al livello 2, indice 2 si trova in a +@end example + +@node Parametri per valore/riferimento +@subsubsection Passare parametri di funzione per valore o per riferimento + +In @command{awk}, quando si definisce una funzione, non c'@`e modo di +dichiarare esplicitamente se gli argomenti sono passati @dfn{per valore} +o @dfn{per riferimento}. + +Invece, il modo con cui i parametri sono passati @`e determinato +durante l'esecuzione del programma, +quando la funzione @`e chiamata, nel rispetto della regola seguente: +se l'argomento @`e una variabile di tipo vettoriale, questa @`e passata +per riferimento. Altrimenti, l'argomento @`e passato per valore. + +@cindex chiamare per valore +Passare un argomento per valore significa che quando una funzione @`e chiamata, +le viene fornita una @emph{copia} del valore di quell'argomento. Il chiamante +pu@`o usare una variabile il cui valore calcolato viene passato come argomento, ma la +funzione chiamata non la riconosce come variabile; riconosce solo il valore +assunto dall'argomento. Per esempio, scrivendo il seguente codice: + +@example +pippo = "pluto" +z = mia_funzione(pippo) +@end example + +@noindent +non si deve pensare che l'argomento passato a @code{mia_funzione()} sia ``la +variabile @code{pippo}.'' Invece, @`e corretto considerare l'argomento come la +stringa il cui valore @`e @code{"pluto"}. +Se la funzione @code{mia_funzione()} altera i valori delle sue variabili +locali, ci@`o non influisce su nessun'altra variabile. Quindi, se +@code{mia_funzione()} fa questo: + +@example +function mia_funzione(stringa) +@{ + print stringa + stringa = "zzz" + print stringa +@} +@end example + +@noindent +cambiando cos@`{@dotless{i}} il valore della variabile che @`e il suo primo argomento, ossia +@code{stringa}, il valore di @code{pippo} per il chiamante @emph{non} viene +modificato. Il ruolo svolto da @code{pippo} nella chiamata di +@code{mia_funzione()} termina quando il suo valore (@code{"pluto"}) viene +calcolato. Se la variabile @code{stringa} esiste anche al di fuori di +@code{mia_funzione()}, il corpo della funzione non pu@`o modificare questo valore +esterno, perch@'e esso rimane oscurato durante l'esecuzione di +@code{mia_funzione()} e non pu@`o quindi essere visto o modificato. + +@cindex chiamare per riferimento +@cindex vettori, come parametri di funzione +@cindex funzioni, vettori come parametri di +Tuttavia, quando sono dei vettori a fungere da parametri alle funzioni, questi +@emph{non} vengono copiati. Invece, il vettore stesso @`e reso disponibile per +essere manipolato direttamente dalla funzione. Questo @`e quel che si dice +solitamente una @dfn{chiamata per riferimento}. Le modifiche effettuate su un +vettore passato come parametro all'interno del corpo di una funzione +@emph{sono} visibili all'esterno della funzione. + +@quotation NOTA +Modificare un vettore passato come parametro all'interno di una funzione +pu@`o essere molto pericoloso se non si sta attenti a quel che si sta facendo. +Per esempio: + +@example +function cambialo(vettore, ind, nvalore) +@{ + vettore[ind] = nvalore +@} + +BEGIN @{ + a[1] = 1; a[2] = 2; a[3] = 3 + cambialo(a, 2, "due") + printf "a[1] = %s, a[2] = %s, a[3] = %s\n", + a[1], a[2], a[3] +@} +@end example + +@noindent +stampa @samp{a[1] = 1, a[2] = due, a[3] = 3}, perch@'e +@code{cambialo()} memorizza @code{"due"} nel secondo elemento di @code{a}. +@end quotation + +@cindex indefinite, funzioni +@cindex funzioni indefinite +Alcune implementazioni di @command{awk} consentono di chiamare una +funzione che non @`e stata definita. +Viene solo emesso un messaggio che descrive il problema al momento +dell'esecuzione, se il programma tenta di chiamare quella funzione. +Per esempio: + +@example +BEGIN @{ + if (0) + pippo() + else + pluto() +@} +function pluto() @{ @dots{} @} +# si noti che `pippo' non @`e definito +@end example + +@noindent +Poich@'e la condizione dell'istruzione @samp{if} non risulter@`a mai verificata +in questo caso, +non @`e un problema reale il fatto che +che @code{pippo()} non sia stato definito. Solitamente, tuttavia, +@`e un problema se un programma chiama una funzione indefinita. + +@cindex @dfn{lint}, controlli, funzione indefinita +@cindex controlli @dfn{lint} per funzione indefinita +@cindex funzione indefinita, controlli @dfn{lint} per + +Se si specifica l'opzione @option{--lint} +(@pxref{Opzioni}), +@command{gawk} elenca le chiamate a funzioni indefinite. + +@cindex portabilit@`a, istruzione @code{next} in funzioni definite dall'utente +@cindex @code{next}, istruzione, in funzioni definite dall'utente +Alcune implementazione di @command{awk} emettono un messaggio di errore +se si usa l'istruzione @code{next} +o @code{nextfile} +(@pxref{Istruzione next}, e +@ifdocbook +@ref{Istruzione nextfile}) +@end ifdocbook +@ifnotdocbook +@pxref{Istruzione nextfile}) +@end ifnotdocbook +all'interno di una funzione definita dall'utente. +@command{gawk} non ha questa limitazione. + +@node Istruzione return +@subsection L'istruzione @code{return} +@cindex @code{return}, istruzione@comma{} in funzioni definite dall'utente +@cindex istruzione @code{return}@comma{} in funzioni definite dall'utente + +Come visto in parecchi esempi precedenti, +il corpo di una funzione definita dall'utente pu@`o contenere un'istruzione +@code{return}. +Quest'istruzione restituisce il controllo a quella parte del +del programma @command{awk} che ha effettuato la chiamata. +Pu@`o anche essere usata per restituire un valore da usare nel resto del +programma @command{awk}. +Questo @`e un esempio: + +@display +@code{return} [@var{espressione}] +@end display + +La parte @var{espressione} @`e facoltativa. +Probabilmente per una svista, POSIX non definisce qual @`e il valore +restituito, se si omette @var{espressione}. Tecnicamente parlando, questo +rende il valore restituito indefinito, e quindi, indeterminato. +In pratica, tuttavia, tutte le versioni di @command{awk} restituiscono +semplicemente la stringa nulla, che vale zero se usata +in un contesto che richiede un numero. + +Un'istruzione @code{return} senza una @var{espressione} @`e considerata presente +alla fine di ogni definizione di funzione. +Quindi, se il flusso di esecuzione raggiunge la fine del corpo della +funzione, tecnicamente la funzione +restituisce un valore indeterminato. +In pratica, restituisce la stringa nulla. @command{awk} +@emph{non} emette alcun messaggio di avvertimento se si usa +il valore restituito di una tale funzione. + +Talvolta pu@`o capitare di scrivere una funzione per quello che fa, non per +quello che restituisce. Una tale funzione corrisponde a una funzione +@code{void} in C, C++, o Java, o a una @code{procedure} in Ada. +Quindi, pu@`o essere corretto non +restituire alcun valore; basta fare attenzione a non usare poi il +valore restituito da una tale funzione. + +Quello che segue @`e un esempio di una funzione definita dall'utente +che restituisce un valore che @`e +il numero pi@`u alto presente tra gli elementi di un vettore: + +@example +function massimo(vettore, i, max) +@{ + for (i in vettore) @{ + if (max == "" || vettore[i] > max) + max = vettore[i] + @} + return max +@} +@end example + +@cindex programmazione, convenzioni di, parametri di funzione +@cindex convenzioni di programmazione, parametri di funzione +@noindent +La chiamata a @code{massimo()} ha un solo argomento, che @`e il nome di +un vettore. Le variabili locali @code{i} e @code{max} non vanno intese +come argomenti; nulla vieta di passare pi@`u di un argomento +a @code{massimo()} ma i risultati sarebbero strani. Gli spazi extra prima +di @code{i} nella lista dei parametri della funzione indicano che @code{i} e +@code{max} sono variabili locali. +@`E consigliabile seguire questa convenzione quando si definiscono delle funzioni. + +Il programma seguente usa la funzione @code{massimo()}. Carica un vettore, +richiama @code{massimo()}, e quindi elenca il numero massimo contenuto in +quel vettore: + +@example +function massimo(vettore, i, max) +@{ + for (i in vettore) @{ + if (max == "" || vettore[i] > max) + max = vettore[i] + @} + return max +@} + +# Carica tutti i campi di ogni record in numeri. +@{ + for (i = 1; i <= NF; i++) + numeri[NR, i] = $i +@} + +END @{ + print massimo(numeri) +@} +@end example + +Dato il seguente input: + +@example + 1 5 23 8 16 +44 3 5 2 8 26 +256 291 1396 2962 100 +-6 467 998 1101 +99385 11 0 225 +@end example + +@noindent +il programma trova (come si pu@`o immaginare) che 99.385 @`e il +valore pi@`u alto contenuto nel vettore. + +@node Variabili di tipo dinamico +@subsection Funzioni e loro effetti sul tipo di una variabile + +@command{awk} @`e un linguaggio molto fluido. +@`E possible che @command{awk} non sia in grado di stabilire se un +identificativo rappresenta una variabile scalare o un vettore, +prima dell'effettiva esecuzione di un programma. +Ecco un esempio di programma commentato: + +@example +function pippo(a) +@{ + a[1] = 1 # il parametro @`e un vettore +@} + +BEGIN @{ + b = 1 + pippo(b) # non valido: errore fatale, tipi variabile in conflitto + + pippo(x) # x non inizializzato, diventa un vettore dinamicamente + x = 1 # a questo punto, non permesso: errore in esecuzione +@} +@end example + +In questo esempio, la prima chiamata a @code{pippo()} genera +un errore fatale, quindi @command{awk} non arriver@`a a segnalare il secondo +errore. Se si commenta la prima chiamata e si riesegue il +programma, a quel punto @command{awk} terminer@`a con un messaggio +relativo al secondo errore. +Solitamente queste cose non causano grossi problemi, ma @`e bene +esserne a conoscenza. + +@node Chiamate indirette +@section Chiamate indirette di funzione + +@cindex indiretta, chiamata di funzione +@cindex chiamata indiretta di funzione +@cindex funzione, puntatori a +@cindex puntatori a funzioni +@cindex differenze tra @command{awk} e @command{gawk}, chiamata indiretta di funzione + +Questa sezione descrive un'estensione avanzata, specifica di @command{gawk}. + +Spesso pu@`o essere utile ritardare la scelta della funzione da chiamare +fino al momento in cui il programma viene eseguito. +Per esempio, potrebbero esserci diversi tipi di record in input, ciascuno +dei quali dovrebbe essere elaborato in maniera differente. + +Solitamente, si userebbe una serie di istruzioni @code{if}-@code{else} +per decidere quale funzione chiamare. Usando la chiamata @dfn{indiretta} +a una funzione, si pu@`o assegnare il nome della funzione da chiamare a +una variabile di tipo stringa, e usarla per chiamare la funzione. +Vediamo un esempio. + +Si supponga di avere un file con i punteggi ottenuti negli esami per i +corsi che si stanno seguendo, e che si desideri ottenere la somma e la +media dei punteggi ottenuti. +Il primo campo @`e il nome del corso. I campi seguenti sono i nomi delle +funzioni da chiamare per elaborare i dati, fino a un campo ``separatore'' +@samp{dati:}. Dopo il separatore, fino alla fine del record, +ci sono i vari risultati numerici di ogni test. + +Ecco il file iniziale: + +@example +@c file eg/data/class_data1 +Biologia_101 somma media dati: 87.0 92.4 78.5 94.9 +Chimica_305 somma media dati: 75.2 98.3 94.7 88.2 +Inglese_401 somma media dati: 100.0 95.6 87.1 93.4 +@c endfile +@end example + +Per elaborare i dati, si potrebbe iniziare a scrivere: + +@example +@{ + corso = $1 + for (i = 2; $i != "dati:"; i++) @{ + if ($i == "somma") + somma() # elabora l'intero record + else if ($i == "media") + media() + @dots{} # e cos@`{@dotless{i}} via + @} +@} +@end example + +@noindent +Questo stile di programmazione funziona, ma pu@`o essere scomodo. +Con la chiamata @dfn{indiretta} di funzione, si pu@`o richiedere a @command{gawk} +di usare il @emph{valore} di una variabile come @emph{nome} della funzione da +chiamare. + +@cindex @code{@@}, notazione per la chiamata indiretta di funzioni +@cindex chiamata indiretta di funzioni, notazione @code{@@} +La sintassi @`e simile a quella di una normale chiamata di funzione: +un identificativo, seguito immediatamente da una parentesi aperta, +qualche argomento, e una parentesi chiusa, con l'aggiunta di un carattere +@samp{@@} all'inizio: + +@example +quale_funzione = "somma" +risultato = @@quale_funzione() # chiamata della funzione somma() +@end example + +Ecco un intero programma che elabora i dati mostrati sopra, +usando la chiamata indiretta di funzioni: + +@example +@c file eg/prog/indirectcall.awk +# chiamataindiretta.awk --- esempio di chiamata indiretta di funzioni +@c endfile +@ignore +@c file eg/prog/indirectcall.awk +# +# Arnold Robbins, arnold@skeeve.com, Public Domain +# January 2009 +@c endfile +@end ignore + +@c file eg/prog/indirectcall.awk +# media --- calcola la media dei valori dei campi $primo - $ultimo + +function media(primo, ultimo, somma, i) +@{ + somma = 0; + for (i = primo; i <= ultimo; i++) + somma += $i + + return somma / (ultimo - primo + 1) +@} + +# somma --- restituisce la somma dei valori dei campi $primo - $ultimo + +function somma(primo, ultimo, totale, i) +@{ + max = 0; + for (i = primo; i <= ultimo; i++) + totale += $i + + return totale +@} +@c endfile +@end example + +Queste due funzioni presuppongono che si lavori con dei campi; quindi, +i parametri @code{primo} e @code{ultimo} indicano da quale campo iniziare +e fino a quale arrivare. +Per il resto, eseguono i calcoli richiesti, che sono i soliti: + +@example +@c file eg/prog/indirectcall.awk +# Per ogni record, +# stampa il nome del corso e le statistiche richieste +@{ + nome_corso = $1 + gsub(/_/, " ", nome_corso) # Rimpiazza _ con spazi + + # trova campo da cui iniziare + for (i = 1; i <= NF; i++) @{ + if ($i == "dati:") @{ + inizio = i + 1 + break + @} + @} + + printf("%s:\n", nome_corso) + for (i = 2; $i != "dati:"; i++) @{ + quale_funzione = $i + printf("\t%s: <%s>\n", $i, @@quale_funzione(inizio, NF) "") + @} + print "" +@} +@c endfile +@end example + +Questo @`e il ciclo principale eseguito per ogni record. +Stampa il nome del corso (con le +lineette basse sostituite da spazi). Trova poi l'inizio dei dati veri +e propri, salvandolo in @code{inizio}. +L'ultima parte del codice esegue un ciclo per ogni nome di funzione +(da @code{$2} fino al separatore, @samp{dati:}), chiamando la funzione +il cui nome @`e specificato nel campo. La chiamata di funzione indiretta +compare come parametro nella chiamata a @code{printf}. +(La stringa di formattazione di @code{printf} usa @samp{%s} come +specificatore di formato, affinch@'e sia possibile usare funzioni +che restituiscano sia stringhe che numeri. Si noti che il risultato +della chiamata indiretta @`e concatenato con la stringa nulla, in modo da +farlo considerare un valore di tipo stringa). + +Ecco il risultato dell'esecuzione del programma: + +@example +$ @kbd{gawk -f chiamataindiretta.awk dati_dei_corsi} +@print{} Biologia 101: +@print{} somma: <352.8> +@print{} media: <88.2> +@print{} +@print{} Chimica 305: +@print{} somma: <356.4> +@print{} media: <89.1> +@print{} +@print{} Inglese 401: +@print{} somma: <376.1> +@print{} media: <94.025> +@end example + +La possibilit@`a di usare la chiamata indiretta di funzioni @`e pi@`u potente +di quel che si possa pensare inizialmente. +I linguaggi C e C++ forniscono ``puntatori di funzione'' che +sono un metodo per chiamare una funzione scelta al momento dell'esecuzione. +Uno dei pi@`u noti usi di questa funzionalit@`a @`e +la funzione C @code{qsort()}, che ordina un vettore usando il famoso +algoritmo noto come ``quicksort'' +(si veda @uref{http://en.wikipedia.org/wiki/Quicksort, l'articolo di Wikipedia} +per ulteriori informazioni). Per usare questa funzione, si specifica un +puntatore a una funzione di confronto. Questo meccanismo consente +di ordinare dei dati arbitrari in una maniera arbitraria. + +Si pu@`o fare qualcosa di simile usando @command{gawk}, cos@`{@dotless{i}}: + +@example +@c file eg/lib/quicksort.awk +# quicksort.awk --- Algoritmo di quicksort, con funzione di confronto +# fornita dall'utente +@c endfile +@ignore +@c file eg/lib/quicksort.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# January 2009 + +@c endfile +@end ignore +@c file eg/lib/quicksort.awk + +# quicksort --- Algoritmo di quicksort di C.A.R. Hoare. +# Si veda Wikipedia o quasi ogni libro +# che tratta di algoritmi o di informatica. +@c endfile +@ignore +@c file eg/lib/quicksort.awk +# +# Adattato da B.W. Kernighan & D.M. Ritchie +# The C Programming Language +# (Englewood Cliffs, NJ: Prentice Hall, 1988) +# Seconda Edizione, pagina 110 +@c endfile +@end ignore +@c file eg/lib/quicksort.awk + +function quicksort(dati, sinistra, destra, minore_di, i, ultimo) +@{ + if (sinistra >= destra) # non fa nulla se il vettore contiene + return # meno di due elementi + + quicksort_scambia(dati, sinistra, int((sinistra + destra) / 2)) + ultimo = sinistra + for (i = sinistra + 1; i <= destra; i++) + if (@@minore_di(dati[i], dati[sinistra])) + quicksort_scambia(dati, ++ultimo, i) + quicksort_scambia(dati, sinistra, ultimo) + quicksort(dati, sinistra, ultimo - 1, minore_di) + quicksort(dati, ultimo + 1, destra, minore_di) +@} + +# quicksort_scambia --- funzione ausiliaria per quicksort, +# sarebbe meglio fosse nel programma principale + +function quicksort_scambia(dati, i, j, salva) +@{ + salva = dati[i] + dati[i] = dati[j] + dati[j] = salva +@} +@c endfile +@end example + +La funzione @code{quicksort()} riceve il vettore @code{dati}, gli +indici iniziali e finali da ordinare +(@code{sinistra} e @code{destra}), e il nome di una funzione che +esegue un confronto ``minore di''. Viene quindi eseguito +l'algoritmo di quicksort. + +Per fare uso della funzione di ordinamento, torniamo all'esempio +precedente. La prima cosa da fare @`e di scrivere qualche funzione +di confronto: + +@example +@c file eg/prog/indirectcall.awk +# num_min --- confronto numerico per minore di + +function num_min(sinistra, destra) +@{ + return ((sinistra + 0) < (destra + 0)) +@} + +# num_magg_o_ug --- confronto numerico per maggiore o uguale + +function num_magg_o_ug(sinistra, destra) +@{ + return ((sinistra + 0) >= (destra + 0)) +@} +@c endfile +@end example + +La funzione @code{num_magg_o_ug()} serve per ottenere un ordinamento +decrescente (dal numero pi@`u alto al pi@`u basso); quando @`e usato +per eseguire un test per ``minore di'', in realt@`a fa l'opposto +(maggiore o uguale a), il che conduce a ottenere dati ordinati +in ordine decrescente. + +Poi serve una funzione di ordinamento. +Come parametri ha i numeri del campo iniziale e di quello finale, +e il nome della funzione di confronto. +Costruisce un vettore con +i dati e richiama appropriatamente @code{quicksort()}; quindi formatta i +risultati mettendoli in un'unica stringa: + +@example +@c file eg/prog/indirectcall.awk +# ordina --- ordina i dati a seconda di `confronta' +# e li restituisce come un'unica stringa + +function ordina(primo, ultimo, confronta, dati, i, risultato) +@{ + delete dati + for (i = 1; primo <= ultimo; primo++) @{ + dati[i] = $primo + i++ + @} + + quicksort(dati, 1, i-1, confronta) + + risultato = dati[1] + for (i = 2; i in dati; i++) + risultato = risultato " " dati[i] + + return risultato +@} +@c endfile +@end example + +Per finire, le due funzioni di ordinamento chiamano la funzione +@code{ordina()}, passandole i nomi delle due funzioni di confronto: + +@example +@c file eg/prog/indirectcall.awk +# ascendente --- ordina i dati in ordine crescente +# e li restituisce sotto forma di stringa + +function ascendente(primo, ultimo) +@{ + return ordina(primo, ultimo, "num_min") +@} + +# discendente --- ordina i dati in ordine decrescente +# e li restituisce sotto forma di stringa + +function discendente(primo, ultimo) +@{ + return ordina(primo, ultimo, "num_magg_o_ug") +@} +@c endfile +@end example + +Ecco una versione estesa del @value{DF}: + +@example +@c file eg/data/class_data2 +Biologia_101 somma media ordina discendente dati: 87.0 92.4 78.5 94.9 +Chimica_305 somma media ordina discendente dati: 75.2 98.3 94.7 88.2 +Inglese_401 somma media ordina discendente dati: 100.0 95.6 87.1 93.4 +@c endfile +@end example + +Per finire, questi sono i risultati quando si esegue il programma +in questa versione migliorata: + +@example +$ @kbd{gawk -f quicksort.awk -f indirettacall.awk class_data2} +@print{} Biologia 101: +@print{} somma: <352.8> +@print{} media: <88.2> +@print{} ascendente: <78.5 87.0 92.4 94.9> +@print{} discendente: <94.9 92.4 87.0 78.5> +@print{} +@print{} Chimica 305: +@print{} somma: <356.4> +@print{} media: <89.1> +@print{} ascendente: <75.2 88.2 94.7 98.3> +@print{} discendente: <98.3 94.7 88.2 75.2> +@print{} +@print{} Inglese 401: +@print{} somma: <376.1> +@print{} media: <94.025> +@print{} ascendente: <87.1 93.4 95.6 100.0> +@print{} discendente: <100.0 95.6 93.4 87.1> +@end example + +Un altro esempio in cui le chiamate indirette di funzione sono utili +@`e costituito dall'elaborazione di vettori. La descrizione si pu@`o trovare +@ref{Visitare vettori}. + +Occorre ricordarsi di anteporre il carattere @samp{@@} prima di una +chiamata indiretta di funzione. + +A partire dalla @value{PVERSION} 4.1.2 di @command{gawk}, le chiamate +indirette di funzione +possono anche essere usate per chiamare funzioni predefinite e con +funzioni di estensione +(@pxref{Estensioni dinamiche}). Ci sono alcune limitazioni nel richiamare +in maniera indiretta delle funzioni predefinite, come qui dettagliato: + +@itemize @value{BULLET} +@item +Non si pu@`o passare una costante @dfn{regexp} a una funzione predefinita +effettuando una chiamata di funzione indiretta.@footnote{Questa +limitazione potrebbe cambiare in una futura versione; +per appurarlo, si controlli la documentazione che accompagna +la versione in uso di @command{gawk}.} +Quanto sopra vale per le funzioni +@code{sub()}, @code{gsub()}, @code{gensub()}, @code{match()}, +@code{split()} e @code{patsplit()}. + +@item +Nel chiamare @code{sub()} o @code{gsub()}, sono accettati solo due argomenti, +poich@'e queste funzioni sono atipiche, in quanto aggiornano il loro terzo +argomento. Questo significa che verr@`a sempre aggiornato l'argomento di +default, @code{$0}. +@end itemize + +@command{gawk} fa del suo meglio per rendere efficiente la chiamata indiretta +di funzioni. Per esempio, nel ciclo seguente: + +@example +for (i = 1; i <= n; i++) + @@quale_funzione() +@end example + +@noindent +@command{gawk} ricerca solo una volta quale funzione chiamare. + +@node Sommario delle funzioni +@section Sommario + +@itemize @value{BULLET} +@item +@command{awk} include delle funzioni predefinite e consente all'utente +di definire le sue proprie funzioni. + +@item +POSIX @command{awk} include tre tipi di funzioni predefinite: numeriche, di +stringa, e di I/O. @command{gawk} prevede funzioni per ordinare vettori, per +lavorare con valori che rappresentano marcature temporali, +per la manipolazione di bit, +per determinare il tipo di una variabile (vettoriale piuttosto che scalare), e +programmi per l'internazionalizzazione e la localizzazione. @command{gawk} +prevede anche parecchie estensioni ad alcune funzioni standard, tipicamente +nella forma di ulteriori argomenti. + +@item +Le funzioni accettano zero o pi@`u argomenti e restituiscono un valore. Le +espressioni che specificano il valore di ogni argomento sono valutate +completamente prima della chiamata +a una funzione. L'ordine di valutazione di questi argomenti non @`e definito. +Il valore restituito dalla funzione pu@`o essere ignorato. + +@item +La gestione delle barre inverse in @code{sub()} e @code{gsub()} non @`e +semplice. +@`E pi@`u semplice nella funzione di @command{gawk} @code{gensub()}, +ma anche questa funzione richiede attenzione quando la si usa. + +@item +Le funzioni definite dall'utente consentono importanti funzionalit@`a ma hanno +anche alcune ineleganze sintattiche. In una chiamata di funzione non si pu@`o +inserire alcuno spazio tra il nome della funzione e la parentesi sinistra +aperta che inizia la lista degli argomenti. Inoltre, non c'@`e nessuna +prescrizione per le variabili locali, e per questo la +convenzione in uso @`e di aggiungere parametri extra, e di separarli visivamente +dai parametri veri e propri inserendo degli spazi bianchi prima di essi. + +@item +Le funzioni definite dall'utente possono chiamare altre +funzioni definite dall'utente (oltre a quelle predefinite) +e possono chiamare se stesse ricorsivamente. I parametri di funzione +``nascondono'' qualsiasi variabile globale che abbia lo stesso nome. +Non si pu@`o usare il nome di una variabile riservata (p.es. @code{ARGC}) +come nome di un parametro in funzioni definite dall'utente. + +@item +I valori scalari sono passati alle funzioni definite dall'utente +per valore. I parametri che sono dei vettori sono passati alle funzioni +per riferimento; ogni modifica fatta dalla funzione a un parametro che +sia un vettore @`e quindi visibile dopo aver eseguito quella funzione. + +@item +L'istruzione @code{return} serve per tornare indietro da una funzione definita +dall'utente. Un'espressione opzionale diviene il valore restituito dalla +funzione. Una funzione pu@`o solo restituire valori di tipo scalare. + +@item +Se una variabile che non @`e stata mai usata @`e passata a una funzione +definita dall'utente, il modo con cui quella funzione elabora la variabile +ne pu@`o determinare il tipo: o scalare o vettoriale. + +@item +@command{gawk} consente la chiamata indiretta di funzioni usando una sintassi +speciale. Impostando una variabile al nome di una funzione, si pu@`o +determinare al momento dell'esecuzione che funzione sar@`a chiamata in un certo +punto del programma. Questo equivale a usare un puntatore a una funzione nei +linguaggi C e C++. + +@end itemize + + +@ifnotinfo +@part @value{PART2}Risoluzione di problemi con @command{awk} +@end ifnotinfo + +@ifdocbook +La Parte II mostra come usare @command{awk} e @command{gawk} per risolvere +problemi. Qui c'@`e il codice di molti programmi, da leggere e da cui si pu@`o +imparare. @`E composta dai seguenti capitoli: + +@itemize @value{BULLET} +@item +@ref{Funzioni di libreria} + +@item +@ref{Programmi di esempio} +@end itemize +@end ifdocbook + +@node Funzioni di libreria +@chapter Una libreria di funzioni @command{awk} +@cindex libreria di funzioni @command{awk} +@cindex funzioni di libreria +@cindex funzioni definite dall'utente, libreria di + +@iftex +La +@end iftex +@ref{Funzioni definite dall'utente} descrive come scrivere le proprie +funzioni @command{awk} personali. Scrivere funzioni @`e importante, perch@'e +consente di incapsulare in un unico contenitore algoritmi e azioni di +programma. Semplifica la programmazione, rendendo lo sviluppo di un programma +pi@`u gestibile, e rendendo i programmi pi@`u leggibili. + +@cindex Kernighan, Brian +@cindex Plauger, P.J.@: +Nel loro autorevole libro del 1976, +@cite{Software Tools},@footnote{Purtroppo, a distanza di oltre 35 anni, +molte delle +lezioni impartite da questo libro devono ancora essere apprese da un gran +numero di programmatori professionisti.} +Brian Kernighan e P.J.@: Plauger hanno scritto: + +@quotation +A programmare bene non s'impara dai concetti generali, ma vedendo come +programmi complessi possono essere resi puliti, facili da leggere, +facili da manutenere e modificare, +strutturati in modo comprensibile, efficienti e affidabili, +applicando il buon senso e delle buone pratiche di programmazione. +Lo studio attento e l'imitazione di buoni programmi conduce a una migliore +scrittura. +@end quotation + +In effetti, loro reputavano quest'idea tanto importante da mettere questa +frase sulla copertina del libro. Poich@'e credo fermamente che la loro +affermazione sia corretta, questo @value{CHAPTER} e +@iftex +il +@end iftex +@ref{Programmi di esempio} +forniscono una corposa raccolta di codice da leggere e, si spera, da cui +imparare. + +Questo @value{CHAPTER} illustra una libreria di utili funzioni @command{awk}. +Molti dei programmi descritti nel seguito di questo @value{DOCUMENT} +usano queste funzioni. +Le funzioni sono illustrate progressivamente, dalla pi@`u semplice alla pi@`u +complessa. + +@cindex Texinfo +@iftex +La +@end iftex +@ref{Programma extract} +illustra un programma che si pu@`o usare per estrarre il codice sorgente +degli esempi di funzioni di libreria e di programmi dal sorgente Texinfo +di questo @value{DOCUMENT}. +(Questo @`e gi@`a stato fatto durante la preparazione della distribuzione +di @command{gawk}.) + +@ifclear FOR_PRINT +Chi avesse scritto una o pi@`u funzioni @command{awk} utili e di uso +generale, e volesse metterle a disposizione della comunit@`a degli utenti di +@command{awk}, pu@`o leggere le informazioni contenute in +@ref{Come contribuire}. +@end ifclear + +@cindex portabilit@`a, programmi di esempio +I programmi contenuti in questo @value{CHAPTER} e in +@ref{Programmi di esempio}, +utilizzano anche le funzionalit@`a specifiche di @command{gawk}. +Riscrivere questi programmi per implementazioni di @command{awk} diverse +@`e piuttosto semplice: + +@itemize @value{BULLET} +@item +I messaggi di errore diagnostici sono inviati a @file{/dev/stderr}. +Usare @samp{| "cat 1>&2"} al posto di @samp{> "/dev/stderr"} se il sistema +in uso non ha un @file{/dev/stderr}, o se non @`e possibile usare +@command{gawk}. + +@item +Alcuni programmi usano @code{nextfile} +(@pxref{Istruzione nextfile}) +per evitare di leggere gli input ancora non letti dal file in input corrente. + +@item +@c 12/2000: Thanks to Nelson Beebe for pointing out the output issue. +@cindex distinzione maiuscolo/minuscolo, programmi di esempio +@cindex @code{IGNORECASE}, variabile, nei programmi di esempio +@cindex variabile @code{IGNORECASE}, nei programmi di esempio +Infine, alcuni dei programmi scelgono di ignorare la distinzione tra maiuscolo e +minuscolo nei loro input, assegnando il valore uno a @code{IGNORECASE}. +Si pu@`o ottenere quasi lo stesso effetto@footnote{I risultati non sono identici. +L'output del record trasformato sar@`a tutto in minuscolo, mentre +@code{IGNORECASE} preserva il contenuto originale del record in input.} +aggiungendo la seguente regola +all'inizio del programma: + +@example +# ignora maiuscolo/minuscolo +@{ $0 = tolower($0) @} +@end example + +@noindent +Inoltre, si verifichi che tutte le @dfn{regexp} e le costanti +di tipo stringa usate nei confronti utilizzano solo lettere minuscole. +@end itemize + +@menu +* Nomi di variabili di libreria:: Che nomi @`e meglio dare alle variabili + private globali nelle funzioni di libreria. +* Funzioni di tipo generale:: Funzioni di uso generale. +* Gestione File Dati:: Funzioni per gestire file-dati specificati + sulla riga di comando. +* Funzione getopt:: Una funzione per trattare argomenti presenti + sulla riga di comando. +* Funzioni Passwd:: Funzioni per ottenete informazioni + sull'utente [da /etc/passwd]. +* Funzioni Group:: Funzioni per ottenete informazioni + sul gruppo [da /etc/group]. +* Visitare vettori:: Una funzione per visitare vettori di vettori. +* Sommario funzioni di libreria:: Sommario funzioni di libreria +* Esercizi con le librerie:: Esercizi. +@end menu + +@node Nomi di variabili di libreria +@section Dare un nome a variabili globali in funzioni di libreria + +@cindex nomi di vettore/variabile +@cindex nomi di funzione +@cindex questioni sui nomi permessi +@cindex nomi permessi, questioni sui +@cindex programmi @command{awk}, documentazione +@cindex documentazione, di programmi @command{awk} +Per come si @`e sviluppato il linguaggio @command{awk}, le variabili sono +o @dfn{globali} (usabili dall'intero programma) o @dfn{locali} (usabili solo +in una specifica funzione). Non c'@`e uno stato intermedio analogo alle +variabili @code{statiche} in C. + +@cindex variabili globali, per funzioni di libreria +@cindex globali, variabili, per funzioni di libreria +@cindex private, variabili +@cindex variabili private +Le funzioni di libreria hanno spesso necessit@`a di avere variabili globali da +usare per conservare informazioni di stato tra successive chiamate alla +funzione; per esempio, la variabile di @code{getopt()} @code{_opti} +(@pxref{Funzione getopt}). +Tali variabili vengono dette @dfn{private}, poich@'e le sole funzioni che +devono usarle sono quelle della libreria. + +Quando si scrive una funzione di libreria, si dovrebbe cercare di scegliere per +le variabili private dei nomi che non entrano in conflitto con nessuna delle +variabili usate da un'altra funzione di libreria o dal programma principale di +un utente. Per esempio, un nome come @code{i} o @code{j} non @`e una buona +scelta, perch@'e i programmi a livello utente usano spesso nomi di variabile come +questi per le proprie elaborazioni. + +@cindex convenzioni di programmazione, nomi di variabili private +@cindex programmazione, convenzioni di, nomi di variabili private +I programmi di esempio mostrati in questo @value{CHAPTER} usano per le +loro variabili private nomi che iniziano con un trattino basso(@samp{_}). +Generalmente gli utenti +non usano trattini bassi iniziali nei nomi di variabile, cos@`{@dotless{i}} questa convenzione +riduce le possibilit@`a che il nome di variabile coincida con un nome usato +nel programma dell'utente. + +@cindex @code{_} (trattino basso), nei nomi di variabili private +@cindex trattino basso (@code{_}), nei nomi di variabili private +Inoltre, parecchie funzioni di libreria usano un prefisso che suggerisce +quale funzione o gruppo di funzioni usa quelle variabili; per esempio, +@code{_pw_byname()} nelle routine che consultano la lista degli utenti +(@pxref{Funzioni Passwd}). +L'uso di questa convenzione viene raccomandata, poich@'e riduce ulteriormente la +possibilit@`a di conflitti accidentali tra nomi di variabile. Si noti che questa +convenzione pu@`o anche essere usata per i nomi di variabile e per i nomi delle +funzioni private.@footnote{Sebbene tutte le routine di libreria si sarebbero +potute riscrivere usando questa convenzione, ci@`o non @`e stato fatto, per far +vedere come lo stile di programmazione in @command{awk} si @`e evoluto e +per fornire alcuni spunti per questa spiegazione.} + +Come nota finale sui nomi delle variabili, se una funzione rende +disponibile una variabile globale per essere usata da un programma principale, +@`e una buona convenzione quella di far iniziare i nomi di queste variabili con +una lettera maiuscola; per esempio, @code{Opterr} e @code{Optind} di +@code{getopt()} +(@pxref{Funzione getopt}). +La lettera maiuscola iniziale indica che la variabile @`e globale, +mentre il fatto che +il nome della variabile non @`e tutto in lettere maiuscole indica che la variabile +non @`e una delle variabili predefinite di @command{awk}, come @code{FS}. + +@cindex @option{--dump-variables}, opzione, uso per funzioni di libreria +@cindex opzione @option{--dump-variables}, uso per funzioni di libreria +@`E importante anche che @emph{tutte} le variabili nelle funzioni di libreria +che non abbiano la necessit@`a di essere +conservate per tutta la durata del +programma siano, di fatto, dichiarate +come locali.@footnote{L'opzione da riga di comando di @command{gawk} +@option{--dump-variables} @`e utile per verificare questo.} Se ci@`o non viene +fatto, la variabile potrebbe essere usata accidentalmente nel programma +dell'utente, conducendo a errori che sono molto difficili da scoprire: + +@example +function lib_func(x, y, l1, l2) +@{ + @dots{} + # qualche_var dovrebbe essere locale ma per una svista non lo @`e + @var{uso della variabile} qualche_var + @dots{} +@} +@end example + +@cindex vettori associativi, funzioni di libreria e +@cindex libreria di funzioni @command{awk}, vettori associativi e +@cindex funzioni, libreria di, vettori associativi e +@cindex Tcl +Una differente convenzione, comune nella comunit@`a Tcl, @`e quella di usare un +solo vettore associativo che contiene i valori necessari alle funzioni di +libreria, o ``package.'' Questo riduce significativamente il numero degli +effettivi nomi globali in uso. Per esempio, le funzioni descritte in +@ref{Funzioni Passwd} +potrebbero aver usato gli elementi di vettore +@code{@w{PW_data["inizializzato"]}}, +@code{@w{PW_data["totale"]}}, @code{@w{PW_data["contatore"]}}, e +@code{@w{PW_data["awklib"]}}, al posto di @code{@w{_pw_inizializzato}}, +@code{@w{_pw_totale}}, +@code{@w{_pw_awklib}} e +@code{@w{_pw_contatore}}. + +Le convenzioni illustrate in questa @value{SECTION} sono esattamente +quello che indica il termine: convenzioni. Non si @`e obbligati a scrivere +i propri programmi in questo modo: @`e solo auspicabile che lo si faccia. + +@node Funzioni di tipo generale +@section Programmazione di tipo generale + +Questa @value{SECTION} illustra diverse funzioni che sono di uso generale nella +programmazione. + +@menu +* Funzione strtonum:: Da usare se non @`e disponibile la funzione + predefinita @code{strtonum()}. +* Funzione assert:: Una funzione per controllare affermazioni + in programmi @command{awk}. +* Funzione round:: Una funzione per eseguire arrotondamenti + se @code{sprintf()} non lo fa correttamente. +* Funzione random Cliff:: Il generatore Cliff di numeri casuali. +* Funzioni ordinali:: Funzioni per usare caratteri come numeri + e viceversa. +* Funzione join:: Una funzione per fondere un vettore + in una stringa. +* Funzione getlocaltime:: Una funzione per ottenere data e ora nel + formato desiderato. +* Funzione readfile:: Una funzione per leggere un file intero in + un colpo solo. +* Apici alla shell:: Una funzione per passare stringhe + con apici alla shell. +@end menu + +@node Funzione strtonum +@subsection Conversione di stringhe in numeri + +La funzione @code{strtonum()} (@pxref{Funzioni per stringhe}) +@`e un'estensione @command{gawk}. La seguente funzione +fornisce un'implementazione per altre versioni di @command{awk}: + +@example +@c file eg/lib/strtonum.awk +# mystrtonum --- converte stringhe in numeri + +@c endfile +@ignore +@c file eg/lib/strtonum.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# February, 2004 +# Revised June, 2014 + +@c endfile +@end ignore +@c file eg/lib/strtonum.awk +function mystrtonum(str, ret, n, i, k, c) +@{ + if (str ~ /^0[0-7]*$/) @{ + # ottale + n = length(str) + ret = 0 + for (i = 1; i <= n; i++) @{ + c = substr(str, i, 1) + # index() restituisce 0 se c non @`e nella stringa, + # e anche se c == "0" + k = index("1234567", c) + + ret = ret * 8 + k + @} + @} else if (str ~ /^0[xX][[:xdigit:]]+$/) @{ + # esadecimale + str = substr(str, 3) # via 0x iniziale + n = length(str) + ret = 0 + for (i = 1; i <= n; i++) @{ + c = substr(str, i, 1) + c = tolower(c) + # index() restituisce 0 se c non @`e nella stringa, + # e anche se c == "0" + k = index("123456789abcdef", c) + + ret = ret * 16 + k + @} + @} else if (str ~ \ + /^[-+]?([0-9]+([.][0-9]*([Ee][0-9]+)?)?|([.][0-9]+([Ee][-+]?[0-9]+)?))$/) @{ + # numero decimale, eventualmente in virgola mobile + ret = str + 0 + @} else + ret = "NON-UN-NUMERO" + + return ret +@} + +# BEGIN @{ # dati per un test +# a[1] = "25" +# a[2] = ".31" +# a[3] = "0123" +# a[4] = "0xdeadBEEF" +# a[5] = "123.45" +# a[6] = "1.e3" +# a[7] = "1.32" +# a[8] = "1.32E2" +# +# for (i = 1; i in a; i++) +# print a[i], strtonum(a[i]), mystrtonum(a[i]) +# @} +@c endfile +@end example + +La funzione cerca dapprima numeri ottali in stile C (base 8). +Se la stringa in input corrisponde all'espressione regolare che descrive i +numeri ottali, @code{mystrtonum()} esegue il ciclo per ogni carattere presente +nella stringa. Imposta @code{k} all'indice in @code{"1234567"} della cifra +ottale corrente. +Il valore di ritorno sar@`a lo stesso numero della cifra, o zero +se il carattere non c'@`e, il che succeder@`a per ogni cifra @samp{0}. +Questo si pu@`o fare, perch@'e il test di @dfn{regexp} nell'istruzione @code{if} +assicura che vengano scelti per +essere convertiti solo dei numeri ottali. + +Una logica simile si applica al codice che ricerca e converte un +valore esadecimale, che inizia con @samp{0x} o @samp{0X}. +L'uso di @code{tolower()} semplifica il calcolo per trovare +il valore numerico corretto per ogni cifra esadecimale. + +Infine, se la stringa corrisponde alla (piuttosto complicata) @dfn{regexp} per +un intero decimale regolare o per un numero in virgola mobile, il calcolo +@samp{ret = str + 0} fa s@`{@dotless{i}} che @command{awk} converta il valore in un +numero. + +@`E incluso un programma di verifica commentato, in modo che la funzione possa +essere verificata con @command{gawk} e il risultato confrontato con la funzione +predefinita @code{strtonum()}. + +@node Funzione assert +@subsection Asserzioni + +@cindex asserzioni +@cindex @code{assert()}, funzione (libreria C) +@cindex funzione @code{assert()} (libreria C) +@cindex libreria di funzioni @command{awk}, asserzioni +@cindex funzioni, libreria di, asserzioni +@cindex @command{awk}, asserzioni in programmi lunghi +Quando si scrivono grossi programmi, spesso @`e utile sapere se +una condizione o una serie di condizioni @`e verificata oppure no. +Prima di procedere +con un determinato calcolo, si fa un'affermazione su cosa si crede sia +vero. Tale affermazione @`e nota come +@dfn{asserzione}. Il linguaggio C fornisce un file di intestazione +@code{<assert.h>} e una corrispondente macro @code{assert()} che un +programmatore pu@`o utilizzare per fare asserzioni. +Se l'asserzione risulta falsa, la macro @code{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 @code{assert()} @`e simile a questo: + +@example +#include <assert.h> + +int myfunc(int a, double b) +@{ + assert(a <= 5 && b >= 17.1); + @dots{} +@} +@end example + +Se l'asserzione @`e falsa, il programma stampa un messaggio simile a questo: + +@example +prog.c:5: asserzione falsa: `a <= 5 && b >= 17.1' +@end example + +@cindex @code{assert()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{assert()} +Il linguaggio C rende possibile trasformare questa condizione in una stringa +da +usare per stampare il messaggio di diagnosi. Ci@`o in @command{awk} non @`e +possibile, per cui la funzione @code{assert()} scritta in @command{awk} +richiede anche una descrizione +della condizione da verificare, in formato stringa. +La funzione @`e la seguente: + +@example +@c file eg/lib/assert.awk +# assert --- Verifica una condizione. Se questa @`e falsa esce. + +@c endfile +@ignore +@c file eg/lib/assert.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# May, 1993 + +@c endfile +@end ignore +@c file eg/lib/assert.awk +function assert(condizione, stringa) +@{ + if (! condizione) @{ + printf("%s:%d: asserzione falsa: %s\n", + FILENAME, FNR, stringa) > "/dev/stderr" + _assert_exit = 1 + exit 1 + @} +@} + +@group +END @{ + if (_assert_exit) + exit 1 +@} +@end group +@c endfile +@end example + +La funzione @code{assert()} verifica il parametro @code{condizione}. Se +@`e falso, stampa un messaggio sullo standard error, usando il parametro +@code{stringa} per descrivere la condizione non verificata. Poi imposta la +variabile @code{_assert_exit} a uno ed esegue l'istruzione @code{exit}. +L'istruzione @code{exit} salta alla regola @code{END}. Se la regola @code{END} +trova vera la variabile @code{_assert_exit}, esce immediatamente. + +Lo scopo della verifica nella regola @code{END} @`e quello di evitare che venga +eseguita qualsiasi altra eventuale regola @code{END}. +Quando un'asserzione non @`e +verificata, il programma dovrebbe uscire immediatamente. +Se nessuna asserzione +fallisce, @code{_assert_exit} @`e ancora falso quando la regola @code{END} @`e +eseguita normalmente, e le eventuali altre regole @code{END} del programma +vengono eseguite. +Affinch@'e tutto questo funzioni correttamente, @file{assert.awk} dev'essere il +primo file sorgente che viene letto da @command{awk}. +La funzione pu@`o essere usata in un programma nel seguente modo: + +@example +function miafunz(a, b) +@{ + assert(a <= 5 && b >= 17.1, "a <= 5 && b >= 17.1") + @dots{} +@} +@end example + +@noindent +Se l'asserzione non @`e verificata, si vedr@`a un messaggio simile a questo: + +@example +mydata:1357: asserzione falsa: a <= 5 && b >= 17.1 +@end example + +@cindex @code{END}, criterio di ricerca, funzione definita dall'utente @code{assert()} e +@cindex criterio di ricerca @code{END}, funzione definita dall'utente @code{assert()} e +C'@`e un piccolo problema con questa versione di @code{assert()}. +Come visto, una regola @code{END} viene automaticamente aggiunta al programma +che chiama @code{assert()}. Normalmente, se un programma consiste +solo di una regola @code{BEGIN}, i file in input e/o lo standard input non +vengono letti. Tuttavia, ora che il programma ha una regola @code{END}, +@command{awk} tenta di leggere i @value{DF} in input o lo standard input +(@pxref{Usare BEGIN/END}), provocando molto probabilmente la sospensione del +programma come se rimanesse in attesa di input. + +@cindex @code{BEGIN}, criterio di ricerca, funzione definita dall'utente @code{assert()} e +@cindex criterio di ricerca @code{BEGIN}, funzione definita dall'utente @code{assert()} e +C'@`e un modo per aggirare questo problema: +assicurarsi che la regola @code{BEGIN} termini sempre +con un'istruzione @code{exit}. + +@node Funzione round +@subsection Arrotondamento di numeri + +@cindex arrotondare numeri +@cindex numeri, arrotondamento di +@cindex libreria di funzioni @command{awk}, arrotondamento di numeri +@cindex funzioni, libreria di, arrotondamento di numeri +@cindex @code{print}, istruzione, funzione @code{sprintf()} e +@cindex istruzione @code{print}, funzione @code{sprintf()} e +@cindex @code{printf}, istruzione, funzione @code{sprintf()} e +@cindex istruzione @code{printf}, funzione @code{sprintf()} e +@cindex @code{sprintf()}, funzione, istruzioni @code{print}/@code{printf} e +@cindex funzione @code{sprintf()}, istruzioni @code{print}/@code{printf} e +Il modo in cui @code{printf} e @code{sprintf()} +(@pxref{Printf}) +effettuano l'arrotondamento spesso dipende dalla subroutine C @code{sprintf()} +del sistema. Su molte macchine, l'arrotondamento di @code{sprintf()} @`e +@dfn{statistico}, il che significa che non sempre arrotonda un .5 finale per +eccesso, contrariamente alle normali aspettative. Nell'arrotondamento +statistico, .5 arrotonda alla cifra pari, anzich@'e sempre per eccesso, cos@`{@dotless{i}} +1.5 arrotonda a 2 e 4.5 arrotonda a 4. Ci@`o significa che se si sta usando un +formato che fa arrotondamenti (p.es. @code{"%.0f"}), si dovrebbe controllare +quello che fa il sistema che si sta usando. La seguente funzione esegue un +arrotondamento tradizionale; potrebbe essere utile nel caso in cui +l'istruzione @code{printf} +di @command{awk} che si sta usando faccia degli arrotondamenti statistici: + +@cindex @code{round()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{round()} +@example +@c file eg/lib/round.awk +# round.awk --- effettua arrotondamento tradizionale +@c endfile +@ignore +@c file eg/lib/round.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# August, 1996 +@c endfile +@end ignore +@c file eg/lib/round.awk + +function round(x, ival, aval, frazione) +@{ + ival = int(x) # parte intera, int() fa un troncamento + + # vedere se c'@`e la parte frazionale + if (ival == x) # nessuna parte frazionale + return ival # nessun decimale + + if (x < 0) @{ + aval = -x # valore assoluto + ival = int(aval) + frazione = aval - ival + if (frazione >= .5) + return int(x) - 1 # -2.5 --> -3 + else + return int(x) # -2.3 --> -2 + @} else @{ + frazione = x - ival + if (frazione >= .5) + return ival + 1 + else + return ival + @} +@} +@c endfile +@c don't include test harness in the file that gets installed + +# codice per testare, commentato +# @{ print $0, round($0) @} +@end example + +@node Funzione random Cliff +@subsection Il generatore di numeri casuali Cliff +@cindex numeri casuali, generatore Cliff +@cindex Cliff, generatore di numeri casuali +@cindex casuali, numeri, generatore Cliff di +@cindex funzioni, libreria di, numeri casuali Cliff + +Il +@uref{http://mathworld.wolfram.com/CliffRandomNumberGenerator.html, generatore di numeri casuali Cliff} +@`e un generatore di numeri casuali molto semplice che ``passa il test della sfera +del rumore per la casualit@`a non mostrando di avere alcuna struttura.'' +@`E programmato in modo molto semplice, in meno di 10 righe di codice +@command{awk}: + +@cindex @code{cliff_rand()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{cliff_rand()} +@example +@c file eg/lib/cliff_rand.awk +# cliff_rand.awk --- generare numeri casuali con algoritmo di Cliff +@c endfile +@ignore +@c file eg/lib/cliff_rand.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# December 2000 +@c endfile +@end ignore +@c file eg/lib/cliff_rand.awk + +BEGIN @{ _cliff_seme = 0.1 @} + +function cliff_rand() +@{ + _cliff_seme = (100 * log(_cliff_seme)) % 1 + if (_cliff_seme < 0) + _cliff_seme = - _cliff_seme + return _cliff_seme +@} +@c endfile +@end example + +Questo algoritmo richiede un ``seme'' iniziale di 0,1. Ogni nuovo valore +usa il seme corrente come input per il calcolo. +Se la funzione predefinita @code{rand()} +(@pxref{Funzioni numeriche}) +non @`e abbastanza casuale, si pu@`o tentare di usare al suo posto questa funzione. + +@node Funzioni ordinali +@subsection Tradurre tra caratteri e numeri + +@cindex libreria di funzioni @command{awk}, valori di carattere come numeri +@cindex funzioni, libreria di, valori di carattere come numeri +@cindex carattere, valore come numero +@cindex numeri, come valori di carattere +Un'implementazione commerciale di @command{awk} fornisce una funzione +predefinita @code{ord()}, che prende un carattere e restituisce il valore +numerico per quel carattere nella rappresentazione dei caratteri +di quella particolare macchina. Se la +stringa passata a @code{ord()} ha pi@`u di un carattere, viene usato solo il +primo. + +L'inverso di questa funzione @`e @code{chr()} (dalla funzione con lo stesso nome +in Pascal), che, dato un numero, restituisce il corrispondente carattere. +Entrambe le funzioni si possono scrivere molto bene usando @command{awk}; +non vi @`e nessun reale motivo per inglobarle come funzioni predefinite +@command{awk}: + +@cindex @code{ord()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{ord()} +@cindex @code{chr()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{chr()} +@cindex @code{_ord_init()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{_ord_init()} +@example +@c file eg/lib/ord.awk +# ord.awk --- implementa ord e chr + +# Identificatori globali: +# _ord_: valori numerici indicizzati da caratteri +# _ord_init: funzione per inizializzare _ord_ +@c endfile +@ignore +@c file eg/lib/ord.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# 16 January, 1992 +# 20 July, 1992, revised +@c endfile +@end ignore +@c file eg/lib/ord.awk + +BEGIN @{ _ord_init() @} + +function _ord_init( basso, alto, i, t) +@{ + basso = sprintf("%c", 7) # BEL @`e ascii 7 + if (basso == "\a") @{ # ascii regolare + basso = 0 + alto = 127 + @} else if (sprintf("%c", 128 + 7) == "\a") @{ + # ascii, con il primo bit a 1 (mark) + basso = 128 + alto = 255 + @} else @{ # ebcdic(!) + basso = 0 + alto = 255 + @} + + for (i = basso; i <= alto; i++) @{ + t = sprintf("%c", i) + _ord_[t] = i + @} +@} +@c endfile +@end example + +@cindex serie di caratteri (codifiche dei caratteri da parte della macchina) +@cindex ASCII +@cindex EBCDIC +@cindex Unicode +@cindex bit di parit@`a (in ASCII) +@cindex @dfn{mark}, bit di parit@`a (in ASCII) +Alcune spiegazioni riguardo ai numeri usati da @code{_ord_init()} +non guastano. +La serie di caratteri pi@`u importante oggi in uso @`e nota come +ASCII.@footnote{La situazione sta per@`o +cambiando: molti sistemi usano Unicode, una serie di caratteri molto ampia +che comprende ASCII al suo interno. +Nei sistemi che supportano interamente Unicode, +un carattere pu@`o occupare fino a 32 bit, facendo diventare +i semplici test usati qui eccessivamente complessi.} +Sebbene un byte a +8 bit possa contenere 256 valori distinti (da 0 a 255), ASCII definisce solo i +caratteri che usano i valori da 0 a 127.@footnote{ASCII +@`e stato esteso in molti paesi per usare i valori da 128 a 255 includendo +i caratteri specifici del paese. Se il sistema in uso si avvale di queste +estensioni, si pu@`o semplificare @code{_ord_init()} per eseguire un ciclo da +0 a 255.} Nel lontano passato, +almeno un produttore di microcomputer +@c Pr1me, blech +ha usato ASCII, ma con una parit@`a di tipo @dfn{mark}, cio@`e con il bit pi@`u a +sinistra sempre a 1. Questo significa che su questi sistemi i caratteri +ASCII hanno valori numerici da 128 a 255. +Infine, i grandi elaboratori centrali usano la serie di caratteri EBCDIC, che +prevede tutti i 256 valori. +Ci sono altre serie di caratteri in uso su alcuni sistemi pi@`u vecchi, ma non +vale la pena di considerarli: + +@example +@c file eg/lib/ord.awk +function ord(str, c) +@{ + # solo il primo carattere @`e d'interesse + c = substr(str, 1, 1) + return _ord_[c] +@} + +function chr(c) +@{ + # trasforma c in un numero aggiungendo uno 0 + return sprintf("%c", c + 0) +@} +@c endfile + +#### programma di verifica #### +# BEGIN @{ +# for (;;) @{ +# printf("immetti un carattere: ") +# if (getline var <= 0) +# break +# printf("ord(%s) = %d\n", var, ord(var)) +# @} +# @} +@c endfile +@end example + +Un ovvio miglioramento a queste funzioni @`e quello di spostare il codice per la +funzione @code{@w{_ord_init}} nel corpo della regola @code{BEGIN}. +Il programma @`e +stato scritto inizialmente in questo modo per comodit@`a di sviluppo. +C'@`e un ``programma di verifica'' in una regola @code{BEGIN}, per verificare +la funzione. @`E commentato, per poter essere eventualmente usato in produzione. + +@node Funzione join +@subsection Trasformare un vettore in una sola stringa + +@cindex libreria di funzioni @command{awk}, trasformare vettori in stringhe +@cindex funzioni, libreria di, trasformare vettori in stringhe +@cindex stringhe, trasformare vettori in +@cindex vettori, trasformare in stringhe +Quando si fanno elaborazioni su stringhe, spesso @`e utile poter unire +tutte le stringhe di un vettore in una lunga stringa. La funzione seguente, +@code{join()}, svolge questo compito. Verr@`a utilizzata nel seguito in diversi +programmi applicativi +@iftex +(@pxrefil{Programmi di esempio}). +@end iftex +@ifnottex +(@pxref{Programmi di esempio}). +@end ifnottex + +La buona progettazione di una funzione @`e importante; la funzione dev'essere +generale, ma potrebbe anche avere un ragionevole comportamento di default. +Viene chiamata con un vettore e anche con gli indici iniziale e finale degli +elementi del vettore da riunire. +Questo presuppone che gli indici del vettore +siano numerici---una supposizione logica, dato che il vettore probabilmente @`e +stato creato con @code{split()} +(@pxref{Funzioni per stringhe}): + +@cindex @code{join()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{join()} +@example +@c file eg/lib/join.awk +# join.awk --- trasforma un vettore in una stringa +@c endfile +@ignore +@c file eg/lib/join.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# May 1993 +@c endfile +@end ignore +@c file eg/lib/join.awk + +function join(vettore, iniz, fine, separ, risultato, i) +@{ + if (separ == "") + separ = " " + else if (separ == SUBSEP) # valore magico + separ = "" + risultato = vettore[iniz] + for (i = iniz + 1; i <= fine; i++) + risultato = risultato separ vettore[i] + return risultato +@} +@c endfile +@end example + +Un ulteriore argomento opzionale @`e il separatore da usare quando si uniscono +nuovamente le stringhe. Se il chiamante fornisce un valore non nullo, +@code{join()} usa quello; se non viene fornito, +per default ha un valore nullo. +In questo caso, @code{join()} usa uno spazio singolo come separatore +di default +per le stringhe. Se il valore @`e uguale a @code{SUBSEP}, +@code{join()} unisce le stringhe senza un separatore tra di esse. +@code{SUBSEP} serve come valore ``magico'' per indicare che potrebbe non esserci +un separatore tra le stringhe componenti.@footnote{Sarebbe bello +se @command{awk} avesse un operatore di assegnamento per la concatenazione. +La mancanza di un esplicito operatore per la concatenazione rende le operazioni +sulle stringhe pi@`u difficili di quanto potrebbero essere.} + +@node Funzione getlocaltime +@subsection Gestione dell'ora del giorno + +@cindex libreria di funzioni @command{awk}, gestire ora del giorno (marcature temporali) +@cindex funzioni, libreria di, gestione delle ore del giorno +@cindex data e ora, formattate +@cindex marcature temporali, formattate +@cindex ora del giorno, gestire +Le funzioni @code{systime()} e @code{strftime()} descritte nella +@ref{Funzioni di tempo} +forniscono la funzionalit@`a minima necessaria per visualizzare l'ora del giorno +in una forma intelligibile. Sebbene @code{strftime()} offra un'ampia gamma di +formattazioni, i formati di controllo non sono facili da ricordare o +intuitivamente ovvii quando si legge un programma. + +La seguente funzione, @code{getlocaltime()}, riempie un vettore fornito +dall'utente con informazioni sul tempo preformattate. Restituisce una stringa +con data e ora corrente formattata come nel programma di utilit@`a @command{date}: + +@cindex @code{getlocaltime()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{getlocaltime()} +@example +@c file eg/lib/gettime.awk +# getlocaltime.awk --- ottiene l'ora del giorno in un formato usabile +@c endfile +@ignore +@c file eg/lib/gettime.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain, May 1993 +# +@c endfile +@end ignore +@c file eg/lib/gettime.awk + +# Restituisce una stringa nel formato dell'output di date(1) +# Riempie l'argomento del vettore time con valori individuali: +# time["second"] -- secondi (0 - 59) +# time["minute"] -- minuti (0 - 59) +# time["hour"] -- ore (0 - 23) +# time["althour"] -- ore (0 - 12) +# time["monthday"] -- giorno del mese (1 - 31) +# time["month"] -- mese dell'anno (1 - 12) +# time["monthname"] -- nome del mese +# time["shortmonth"] -- nome breve del mese +# time["year"] -- anno modulo 100 (0 - 99) +# time["fullyear"] -- anno completo +# time["weekday"] -- giorno della settimana (domenica = 0) +# time["altweekday"] -- giorno della settimana (luned@`{@dotless{i}} = 0) +# time["dayname"] -- nome del giorno della settimana +# time["shortdayname"] -- nome breve del giorno della settimana +# time["yearday"] -- giorno dell'anno (0 - 365) +# time["timezone"] -- abbreviazione del nome della zona di fuso orario +# time["ampm"] -- designazione di AM o PM +# time["weeknum"] -- numero della settimana, domenica primo giorno +# time["altweeknum"] -- numero della settimana, luned@`{@dotless{i}} primmo giorno + +function getlocaltime(ora, ret, adesso, i) +@{ + # ottiene data e ora una volta sola, + # evitando chiamate di sistema non necessarie + adesso = systime() + + # restituisce l'output in stile date(1) +@c lun 8 giu 2015, 20.39.38, CEST +@c "%a %e %b %Y , %H.%M.%S, %Z" + ret = strftime("%a %e %b %Y, %H.%M.%S, %Z", adesso) + + # clear out target array + delete time + + # immette i valori, forzando i valori numerici + # a essere numerici aggiungendo uno 0 + time["second"] = strftime("%S", adesso) + 0 + time["minute"] = strftime("%M", adesso) + 0 + time["hour"] = strftime("%H", adesso) + 0 + time["althour"] = strftime("%I", adesso) + 0 + time["monthday"] = strftime("%d", adesso) + 0 + time["month"] = strftime("%m", adesso) + 0 + time["monthname"] = strftime("%B", adesso) + time["shortmonth"] = strftime("%b", adesso) + time["year"] = strftime("%y", adesso) + 0 + time["fullyear"] = strftime("%Y", adesso) + 0 + time["weekday"] = strftime("%w", adesso) + 0 + time["altweekday"] = strftime("%u", adesso) + 0 + time["dayname"] = strftime("%A", adesso) + time["shortdayname"] = strftime("%a", adesso) + time["yearday"] = strftime("%j", adesso) + 0 + time["timezone"] = strftime("%Z", adesso) + time["ampm"] = strftime("%p", adesso) + time["weeknum"] = strftime("%U", adesso) + 0 + time["altweeknum"] = strftime("%W", adesso) + 0 + + return ret +@} +@c endfile +@end example + +Gli indici di stringa sono pi@`u facili da usare e leggere rispetto ai +vari formati +richiesti da @code{strftime()}. Il programma @code{alarm} illustrato in +@ref{Programma alarm} +usa questa funzione. +Una progettazione pi@`u generica della funzione @code{getlocaltime()} +avrebbe permesso all'utente di fornire un valore di data e ora +opzionale da usare al posto della data/ora corrente. + +@node Funzione readfile +@subsection Leggere un intero file in una sola volta + +Spesso @`e conveniente avere il contenuto di un intero file disponibile +in memoria, visto +come un'unica stringa. Un modo chiaro e semplice per far ci@`o potrebbe essere +questo: + +@example +function readfile(file, temp, contenuto) +@{ + if ((getline temp < file) < 0) + return + + contenuto = temp + while (getline temp < file) > 0) + contenuto = contenuto RT tmp + + close(file) + return contenuto +@} +@end example + +Questa funzione legge da @code{file} un record alla volta, ricostruendo +l'intero contenuto del file nella variabile locale @code{contenuto}. +Funziona, ma non @`e detto che sia efficiente. + +La funzione seguente, basata su un suggerimento di Denis Shirokov, +legge l'intero contenuto del file in un colpo solo: + +@cindex @code{readfile()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{readfile()} +@example +@c file eg/lib/readfile.awk +# readfile.awk --- legge un intero file in un colpo solo +@c endfile +@ignore +@c file eg/lib/readfile.awk +# +# Idea originale di Denis Shirokov, cosmogen@@gmail.com, aprile 2013 +# +@c endfile +@end ignore +@c file eg/lib/readfile.awk + +function readfile(file, temp, salva_rs) +@{ + salva_rs = RS + RS = "^$" + getline temp < file + close(file) + RS = salva_rs + + return temp +@} +@c endfile +@end example + +Funziona impostando @code{RS} a @samp{^$}, un'espressione regolare che +non trova nessuna corrispondenza se il file ha un contenuto. +@command{gawk} +legge i dati dal file contenuto in @code{temp}, tentando di trovare una +corrispondenza con @code{RS}. +La ricerca dopo ogni lettura non ha mai successo, ma termina +rapidamente, e quindi @command{gawk} inserisce in +@code{temp} l'intero contenuto del file. +(@xref{Record} per informazioni su @code{RT} e @code{RS}.) + +Se @code{file} @`e vuoto, il valore di ritorno @`e la stringa vuota. +Quindi, il codice chiamante pu@`o usare qualcosa simile a questo: + +@example +contenuto = readfile("/qualche/percorso") +if (length(contenuto) == 0) + # file vuoto @dots{} +@end example + +La verifica serve a determinare se il file @`e vuoto o no. Una verifica +equivalente potrebbe essere @samp{contenuto == ""}. + +@xref{Esempio di estensione Readfile} per una funzione di estensione +anch'essa finalizzata a leggere un intero file in memoria. + +@node Apici alla shell +@subsection Stringhe con apici da passare alla shell + +@c included by permission +@ignore +Date: Sun, 27 Jul 2014 17:16:16 -0700 +Message-ID: <CAKuGj+iCF_obaCLDUX60aSAgbfocFVtguG39GyeoNxTFby5sqQ@mail.gmail.com> +Subject: Useful awk function +From: Mike Brennan <mike@madronabluff.com> +To: Arnold Robbins <arnold@skeeve.com> +@end ignore + +Michael Brennan propone il seguente modello di programma, +da lui usato spesso: + +@example +#! /bin/sh + +awkp=' + @dots{} + ' + +@var{specifica_programma_da_eseguire} | awk "$awkp" | /bin/sh +@end example + +Per esempio, un suo programma chiamato @command{flac-edit}@footnote{I +file con suffisso @dfn{flac} contengono normalmente dei brani musicali. +@command{metaflac} @`e un programma che permette di modificare +le informazioni [@dfn{metadati}] contenute all'inizio di un file di tipo +@dfn{flac}.} ha questa forma: + +@example +$ @kbd{flac-edit -song="Whoope! That's Great" file.flac} +@end example + +@command{flac-edit} genera in output il seguente script, da passare alla +shell (@file{/bin/sh}) per essere eseguito: + +@example +chmod +w file.flac +metaflac --remove-tag=TITLE file.flac +LANG=en_US.88591 metaflac --set-tag=TITLE='Whoope! That'"'"'s Great' file.flac +chmod -w file.flac +@end example + +Si noti la necessit@`a di gestire gli apici nello script da passare alla shell. +La funzione +@code{shell_quote()} li prepara nel formato richiesto. +@code{SINGLE} @`e la stringa di un solo +carattere @code{"'"} e @code{QSINGLE} @`e la stringa di tre caratteri +@code{"\"'\""}: + +@example +@c file eg/lib/shellquote.awk +# shell_quote --- pone tra apici un argomento da passare alla shell +@c endfile +@ignore +@c file eg/lib/shellquote.awk +# +# Michael Brennan +# brennan@@madronabluff.com +# September 2014 +@c endfile +@end ignore +@c file eg/lib/shellquote.awk + +function shell_quote(s, # parametro + SINGLE, QSINGLE, i, X, n, ret) # variabili locali +@{ + if (s == "") + return "\"\"" + + SINGLE = "\x27" # apice singolo + QSINGLE = "\"\x27\"" # apice singolo incapsulato + n = split(s, X, SINGLE) + + ret = SINGLE X[1] SINGLE + for (i = 2; i <= n; i++) + ret = ret QSINGLE SINGLE X[i] SINGLE + + return ret +@} +@c endfile +@end example + +@node Gestione File Dati +@section Gestione di @value{DF} + +@cindex file, gestione di +@cindex gestione di file +@cindex libreria di funzioni @command{awk}, gestire file di dati +@cindex funzioni, libreria di, gestire file di dati +Questa @value{SECTION} presenta funzioni utili per gestire +@value{DF} da riga di comando. + +@menu +* Funzione filetrans:: Una funzione per gestire il passaggio da un + file in input al successivo. +* Funzione rewind:: Una funzione per rileggere il file in input. +* Controllo di file:: Controllare che i file in input siano + accessibili. +* File vuoti:: Controllare se i file in input sono vuoti. +* Ignorare assegnamenti di variabili:: Trattare assegnamenti di variabili. + come nomi di file. +@end menu + +@node Funzione filetrans +@subsection Trovare i limiti dei @value{DF} + +@cindex file, gestione di, limiti dei file-dati +@cindex file, inizializzazione e pulizia +Ognuna delle regole @code{BEGIN} ed @code{END} viene eseguita esattamente +solo una volta, rispettivamente all'inizio e alla fine del programma +@command{awk} (@pxref{BEGIN/END}). +Una volta noi (gli autori di @command{gawk}) siamo venuti in contatto +con un utente che +erroneamemnte pensava che le regole @code{BEGIN} venissero eseguite all'inizio +di ogni @value{DF} e le regole @code{END} alla fine di ogni @value{DF}. + +Quando lo abbiamo informato che +non era cos@`{@dotless{i}}, ci ha chiesto di aggiungere un nuovo criterio di ricerca speciale +a @command{gawk}, chiamato @code{BEGIN_FILE} e @code{END_FILE}, che avesse il +comportamento desiderato. Ci ha fornito anche il codice per far questo. + +Non @`e stato necessario aggiungere a @command{gawk} questi criteri di ricerca +speciali; il lavoro si pu@`o fare tranquillamente usando @command{awk}, come +illustrato nel seguente programma di libreria. @`E strutturato in modo da +chiamare due funzioni fornite dall'utente, @code{a_inizio_file()} e +@code{a_fine_file()}, all'inizio e alla fine di ogni @value{DF}. Oltre a risolvere +il problema in sole nove(!) righe di codice, +questa soluzione @`e @emph{portabile}; il +programma funziona con qualsiasi implementazione di @command{awk}: + +@example +# transfile.awk +# +# Dare all'utente un aggancio per il passaggio +# da un file in input a quello successivo +# +# L'utente deve fornire le funzioni a_inizio_file() ed a_fine_file() +# ciascuna delle quali @`e invocata +# quando il file, rispettivamente, +# inizia e finisce. +@c # +@c # Arnold Robbins, arnold@@skeeve.com, Public Domain +@c # January 1992 + +FILENAME != _nome_file_vecchio @{ + if (_nome_file_vecchio != "") + a_fine_file(_nome_file_vecchio) + _nome_file_vecchio = FILENAME + a_inizio_file(FILENAME) +@} + +END @{ a_fine_file(FILENAME) @} +@end example + +Questo file [transfile.awk] dev'essere caricato prima del programma +``principale'' dell'utente, +in modo che la regola ivi contenuta venga eseguita per prima. + +Questa regola dipende dalla variabile di @command{awk} @code{FILENAME}, che +cambia automaticamente per ogni nuovo @value{DF}. Il @value{FN} corrente viene +salvato in una variabile privata, @code{_nome_file_vecchio}. Se @code{FILENAME} non @`e +uguale a @code{_nome_file_vecchio}, inizia l'elaborazioone di un nuovo @value{DF} ed +@`e necessario chiamare @code{a_fine_file()} per il vecchio file. Poich@'e +@code{a_fine_file()} dovrebbe essere chiamato solo se un file @`e stato elaborato, il +programma esegue prima un controllo per assicurarsi che @code{_nome_file_vecchio} non +sia la stringa nulla. Il programma assegna poi il valore corrente di +@value{FN} a @code{_nome_file_vecchio} e chiama @code{a_inizio_file()} per il file. +Poich@'e, come tutte le variabili di @command{awk}, @code{_nome_file_vecchio} @`e +inizializzato alla stringa nulla, questa regola viene eseguita correttamente +anche per il primo @value{DF}. + +Il programma contiene anche una regola @code{END} per completare l'elaborazione +per l'ultimo file. Poich@'e questa regola @code{END} viene prima di qualsiasi +regola @code{END} contenuta nel programma ``principale'', +@code{a_fine_file()} viene +chiamata per prima. Ancora una volta, l'utilit@`a di poter avere pi@`u regole +@code{BEGIN} ed @code{END} dovrebbe risultare chiara. + +@cindex @code{a_inizio_file()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{a_inizio_file()} +@cindex @code{a_fine_file()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{a_fine_file()} +Se lo stesso @value{DF} compare due volte di fila sulla riga di comando, +@code{a_fine_file()} e @code{a_inizio_file()} non vengono eseguite alla fine del primo +passaggio e all'inizio del secondo passaggio. +La versione seguente risolve il problema: + +@example +@c file eg/lib/ftrans.awk +# ftrans.awk --- gestisce il passaggio da un file dati al successivo +# +# L'utente deve fornire le funzioni a_inizio_file() ed a_fine_file() +@c endfile +@ignore +@c file eg/lib/ftrans.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# November 1992 +@c endfile +@end ignore +@c file eg/lib/ftrans.awk + +FNR == 1 @{ + if (_filename_ != "") + a_fine_file(_filename_) + _filename_ = FILENAME + a_inizio_file(FILENAME) +@} + +END @{ a_fine_file(_filename_) @} +@c endfile +@end example + +@iftex +La +@end iftex +@ref{Programma wc} +mostra come utilizzare questa funzione di libreria e come ci@`o +semplifichi la scrittura del programma principale. + +@sidebar Allora perch@'e @command{gawk} ha @code{BEGINFILE} e @code{ENDFILE}? + +Ci si chieder@`a, probabilmente: perch@'e, se le funzioni @code{a_inizio_file()} e +@code{a_fine_file()} possono eseguire il compito, @command{gawk} prevede i +criteri di +ricerca @code{BEGINFILE} e @code{ENDFILE}? + +Buona domanda. Normalmente, se @command{awk} non riesce ad aprire un file, +questo fatto +provoca un errore fatale immediato. In tal caso, per una funzione definita +dall'utente non vi @`e alcun modo di affrontare il problema, giacch@'e la +chiamata verrebbe effettuata +solo dopo aver aperto il file e letto il primo record. +Quindi, la ragione principale di @code{BEGINFILE} @`e quella di dare un +``aggancio'' per gestire i file che non posso essere elaborati. +@code{ENDFILE} esiste per simmetria, e perch@'e consente facilmente +una pulizia "file per file". Per maggiori informazioni si faccia +riferimento alla @ref{BEGINFILE/ENDFILE}. +@end sidebar + +@node Funzione rewind +@subsection Rileggere il file corrente + +@cindex file, leggere un +@cindex file, rileggere un +Un'altra richiesta per una nuova funzione predefinita @`e stata per +una funzione per rileggere il file corrente. +L'utente che l'ha richiesta non voleva dover usare @code{getline} +(@pxref{Getline}) +all'interno di un ciclo. + +Comunque, se non si @`e nella regola @code{END}, @`e piuttosto facile +fare in modo di chiudere il corrente file in input immediatamente +e ricominciare a leggerlo dall'inizio. +In mancanza di un nome migliore, chiameremo la funzione @code{rewind()}: + +@cindex @code{rewind()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{rewind()} +@example +@c file eg/lib/rewind.awk +# rewind.awk --- ricarica il file corrente e ricomincia a leggerlo +@c endfile +@ignore +@c file eg/lib/rewind.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# September 2000 +@c endfile +@end ignore +@c file eg/lib/rewind.awk + +function rewind( i) +@{ + # sposta in alto i rimanenti argomenti + for (i = ARGC; i > ARGIND; i--) + ARGV[i] = ARGV[i-1] + + # assicurarsi che gawk sappia raggiungerli + ARGC++ + + # fa s@`{@dotless{i}} che il file corrente sia il prossimo a essere letto + ARGV[ARGIND+1] = FILENAME + + # do it + nextfile +@} +@c endfile +@end example + +La funzione @code{rewind()} dipende dalla variabile @code{ARGIND} +(@pxref{Variabili auto-assegnate}), che @`e specifica di @command{gawk}. Dipende anche +dalla parola chiave @code{nextfile} (@pxref{Istruzione nextfile}). +Perci@`o, non si dovrebbe chiamarla da una regola @code{ENDFILE}. +(Non sarebbe peraltro necessario, perch@'e @command{gawk} legge il file +successivo non appena la regola @code{ENDFILE} finisce!) + +Occorre prestare attenzione quando si chiama @code{rewind()}. Si pu@`o +provocare una ricorsione infinita se non si sta attenti. Ecco un +esempio di uso: + +@example +$ @kbd{cat dati} +@print{} a +@print{} b +@print{} c +@print{} d +@print{} e + +$ cat @kbd{test.awk} +@print{} FNR == 3 && ! riavvolto @{ +@print{} riavvolto = 1 +@print{} rewind() +@print{} @} +@print{} +@print{} @{ print FILENAME, FNR, $0 @} + +$ @kbd{gawk -f rewind.awk -f test.awk dati } +@print{} data 1 a +@print{} data 2 b +@print{} data 1 a +@print{} data 2 b +@print{} data 3 c +@print{} data 4 d +@print{} data 5 e +@end example + +@node Controllo di file +@subsection Controllare che i @value{DF} siano leggibili + +@cindex risoluzione di problemi, leggibilit@`a file-dati +@cindex leggibilit@`a, file-dati@comma{} controllare la +@cindex file, non elaborare +Normalmente, se si fornisce ad @command{awk} un @value{DF} che non @`e leggibile, +il programma +si arresta con un errore fatale. Ci sono casi in cui sarebbe preferibile +ignorare semplicemente questi file e proseguire.@footnote{Il criterio di +ricerca speciale @code{BEGINFILE} (@pxref{BEGINFILE/ENDFILE}) fornisce un +meccanismo alternativo per trattare i file che non sono leggibili. +Tuttavia, il codice qui proposto fornisce una soluzione portabile.} +Si pu@`o far questo facendo precedere il proprio programma @command{awk} dal +seguente programma: + +@cindex @code{readable.awk}, programma +@example +@c file eg/lib/readable.awk +# readable.awk --- file di libreria per saltare file non leggibili +@c endfile +@ignore +@c file eg/lib/readable.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# October 2000 +# December 2010 +@c endfile +@end ignore +@c file eg/lib/readable.awk + +BEGIN @{ + for (i = 1; i < ARGC; i++) @{ + if (ARGV[i] ~ /^[a-zA-Z_][a-zA-Z0-9_]*=.*/ \ + || ARGV[i] == "-" || ARGV[i] == "/dev/stdin") + continue # assegnamento di variabile o standard input + else if ((getline aperdere < ARGV[i]) < 0) # file non leggibile + delete ARGV[i] + else + close(ARGV[i]) + @} +@} +@c endfile +@end example + +@cindex risoluzione di problemi, funzione @code{getline} +@cindex comando @code{getline}, risoluzione di problemi +@cindex @code{getline}, comando, risoluzione di problemi +Questo codice funziona, perch@'e l'errore di @code{getline} non @`e fatale. +Rimuovendo l'elemento da @code{ARGV} con @code{delete} +si tralascia il file (perch@'e non @`e pi@`u nella lista). +Si veda anche @ref{ARGC e ARGV}. + +Poich@'e per i nomi delle variabili @command{awk} si possono usare solo lettere +dell'alfabeto inglese, di proposito il controllo con espressioni regolari +non usa classi di +carattere come @samp{[:alpha:]} e @samp{[:alnum:]} +(@pxref{Espressioni tra parentesi quadre}). + +@node File vuoti +@subsection Ricerca di file di lunghezza zero + +Tutte le implementazioni note di @command{awk} ignorano senza +mandare alcun messaggio i file di +lunghezza zero. Questo @`e un effetto collaterale del ciclo implicito di +@command{awk} "leggi un record e confrontalo con le regole": quando +@command{awk} cerca di leggere un record da un file vuoto, riceve immediatamente +un'indicazione di fine-file [@dfn{end-of-file}], chiude il file, +e prosegue con il +successivo @value{DF} presente nella riga di comando, @emph{senza} +eseguire alcun codice +di programma @command{awk} a livello di utente. + +Usando la variabile @code{ARGIND} di @command{gawk} +(@pxref{Variabili predefinite}), @`e possibile accorgersi quando un @value{DF} +@`e stato saltato. Simile al file di libreria illustrato in +@ref{Funzione filetrans}, il seguente file di libreria chiama una funzione +di nome @code{zerofile()} che l'utente deve fornire. Gli argomenti passati +sono il @value{FN} e la posizione del file in @code{ARGV}: + +@cindex @code{zerofile.awk}, programma +@example +@c file eg/lib/zerofile.awk +# zerofile.awk --- file di libreria per elaborare file in input vuoti +@c endfile +@ignore +@c file eg/lib/zerofile.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# June 2003 +@c endfile +@end ignore +@c file eg/lib/zerofile.awk + +BEGIN @{ Argind = 0 @} + +ARGIND > Argind + 1 @{ + for (Argind++; Argind < ARGIND; Argind++) + zerofile(ARGV[Argind], Argind) +@} + +ARGIND != Argind @{ Argind = ARGIND @} + +END @{ + if (ARGIND > Argind) + for (Argind++; Argind <= ARGIND; Argind++) + zerofile(ARGV[Argind], Argind) +@} +@c endfile +@end example + +La variabile definita dall'utente @code{Argind} permette al programma +@command{awk} +di tracciare il suo percorso all'interno di @code{ARGV}. Ogniqualvolta il +programma rileva che @code{ARGIND} @`e maggiore di @samp{Argind + 1}, vuol dire +che uno o pi@`u file vuoti sono stati tralasciati. L'azione chiama poi +@code{zerofile()} per ogni file che @`e stato saltato, incrementando +ogni volta @code{Argind}. + +La regola @samp{Argind != ARGIND} tiene semplicemente aggiornato @code{Argind} +nel caso che non ci siano file vuoti. + +Infine, la regola @code{END} prende in considerazione il caso di un qualsiasi +file vuoto alla fine degli argomenti nella riga di comando. Si noti che nella +condizione del ciclo @code{for}, la verifica usa l'operatore @samp{<=}, non +@samp{<}. + +@node Ignorare assegnamenti di variabili +@subsection Trattare assegnamenti di variabile come @value{FNS} + +@cindex assegnamenti di variabile, visti come nomi di file +@cindex file, nomi di, assegnamenti di variabile visti come +@cindex nomi di file, assegnamenti di variabile visti come +Occasionalmente, potrebbe essere pi@`u opportuno che @command{awk} non elabori gli +assegnamenti di variabile presenti sulla riga di comando +(@pxref{Opzioni di assegnamento}). +In particolare, se si ha un @value{FN} che contiene un carattere @samp{=}, +@command{awk} tratta il @value{FN} come un assegnamento e non lo elabora. + +Alcuni utenti hanno suggerito un'opzione aggiuntiva da riga di comando per +@command{gawk} per disabilitare gli assegnamenti dati sulla riga di comando. +Comunque, poche righe di codice di programmazione in un file di libreria +hanno lo stesso effetto: + +@cindex @code{noassign.awk}, programma +@cindex programma @code{noassign.awk} +@example +@c file eg/lib/noassign.awk +# noassign.awk --- file di libreria per evitare la necessit@`a +# di una speciale opzione per disabilitare gli assegnamenti da +# riga di comando +@c endfile +@ignore +@c file eg/lib/noassign.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# October 1999 +@c endfile +@end ignore +@c file eg/lib/noassign.awk + +function disable_assigns(argc, argv, i) +@{ + for (i = 1; i < argc; i++) + if (argv[i] ~ /^[a-zA-Z_][a-zA-Z0-9_]*=.*/) + argv[i] = ("./" argv[i]) +@} + +BEGIN @{ + if (Disabilita_variabili) + disable_assigns(ARGC, ARGV) +@} +@c endfile +@end example + +Il programma va poi eseguito in questo modo: + +@example +awk -v Disabilita_variabili=1 -f noassign.awk -f vostro_programma.awk * +@end example + +La funzione esegue un ciclo che esamina ogni argomento. +Antepone @samp{./} a +qualsiasi argomento che abbia la forma di un assegnamento +di variabile, trasformando cos@`{@dotless{i}} quell'argomento in un @value{FN}. + +L'uso di @code{Disabilita_variabili} consente di disabilitare assegnamenti di +variabile dati sulla riga di comando al momento dell'invocazione, +assegnando alla variabile un valore @dfn{vero}. +Se non viene impostata la variabile @`e inizializzata a zero (cio@`e +@dfn{falso}), e gli argomenti sulla riga di comando +non vengono modificati. + +@node Funzione getopt +@section Elaborare opzioni specificate sulla riga di comando + +@cindex libreria di funzioni @command{awk}, opzioni sulla riga di comando +@cindex funzioni, libreria di, opzioni sulla riga di comando +@cindex riga di comando, opzioni, elaborazione di +@cindex opzioni sulla riga di comando, elaborazione di +@cindex funzioni, libreria di, libreria C +@cindex argomenti, elaborazione di +La maggior parte dei programmi di utilit@`a su sistemi compatibili con POSIX +prevedono opzioni presenti sulla riga di comando che possono essere usate per +cambiare il modo in cui un programma si comporta. @command{awk} @`e un esempio di +tali programmi (@pxref{Opzioni}). +Spesso le opzioni hanno degli @dfn{argomenti} (cio@`e, dati che servono al +programma per eseguire correttamente le opzioni specificate +sulla riga di comando). +Per esempio, l'opzione @option{-F} di @command{awk} richiede di usare la stringa +specificata +come separatore di campo. La prima occorrenza, sulla riga di comando, di +@option{--} o di una stringa che non inizia con @samp{-} segnala la fine +delle opzioni. + +@cindex @code{getopt()}, funzione (libreria C) +@cindex funzione @code{getopt()} (libreria C) +I moderni sistemi Unix hanno una funzione C chiamata @code{getopt()} per +elaborare gli argomenti presenti +sulla riga di comando. Il programmatore fornisce una +stringa che descrive le opzioni, ognuna delle quali consiste di +una sola lettera. Se un'opzione richiede un +argomento, nella stringa l'opzione @`e seguita da due punti. +A @code{getopt()} vengono anche +passati il numero e i valori degli argomenti presenti sulla riga di comando +e viene chiamata in un ciclo. +@code{getopt()} scandisce gli argomenti della riga di comando cercando +le lettere delle opzioni. +A ogni passaggio del ciclo restituisce un carattere +singolo che rappresenta la successiva lettera di opzione trovata, o @samp{?} +se viene trovata un'opzione non prevista. +Quando restituisce @minus{}1, non ci sono ulteriori +opzioni da trattare sulla riga di comando. + +Quando si usa @code{getopt()}, le opzioni che non prevedono argomenti +possono essere raggruppate. +Inoltre, le opzioni che hanno argomenti richiedono obbligatoriamente che +l'argomento sia specificato. +L'argomento pu@`o seguire immediatamente la lettera +dell'opzione, o pu@`o costituire un argomento separato sulla riga di comando. + +Dato un ipotetico programma che ha tre opzioni sulla riga di comando, +@option{-a}, @option{-b} e @option{-c}, dove +@option{-b} richiede un argomento, tutti i seguenti sono modi validi per +invocare il programma: + +@example +programma -a -b pippo -c dati1 dati2 dati3 +programma -ac -bpippo -- dati1 dati2 dati3 +programma -acbpippo dati1 dati2 dati3 +@end example + +Si noti che quando l'argomento @`e raggruppato con la sua opzione, +la parte rimanente +dell'argomento @`e considerato come argomento dell'opzione. +In quest'esempio, @option{-acbpippo} indica che tutte le opzioni +@option{-a}, @option{-b} e @option{-c} sono presenti, +e che @samp{pippo} @`e l'argomento dell'opzione @option{-b}. + +@code{getopt()} fornisce quattro variabili esterne a disposizione del +programmatore: + +@table @code +@item optind +L'indice nel vettore dei valori degli argomenti (@code{argv}) dove si pu@`o +trovare il primo argomento sulla riga di comando che non sia un'opzione. + +@item optarg +Il valore (di tipo stringa) dell'argomento di un'opzione. + +@item opterr +Solitamente @code{getopt()} stampa un messaggio di errore quando trova un'opzione +non valida. Impostando @code{opterr} a zero si disabilita questa funzionalit@`a. +(un'applicazione potrebbe voler stampare un proprio messaggio di errore.) + +@item optopt +La lettera che rappresenta l'opzione sulla riga di comando. +@end table + +Il seguente frammento di codice C mostra come @code{getopt()} potrebbe +elaborare gli argomenti della riga di comando per @command{awk}: + +@example +int +main(int argc, char *argv[]) +@{ + @dots{} + /* stampa un appropriato messaggio */ + opterr = 0; + while ((c = getopt(argc, argv, "v:f:F:W:")) != -1) @{ + switch (c) @{ + case 'f': /* file */ + @dots{} + break; + case 'F': /* separatore di campo */ + @dots{} + break; + case 'v': /* assegnamento di variabile */ + @dots{} + break; + case 'W': /* estensione */ + @dots{} + break; + case '?': + default: + messaggio_di_aiuto(); + break; + @} + @} + @dots{} +@} +@end example + +Incidentalmente, @command{gawk} al suo interno usa la funzione GNU +@code{getopt_long()} per elaborare sia le normali opzioni che quelle lunghe +in stile GNU +(@pxref{Opzioni}). + +L'astrazione fornita da @code{getopt()} @`e molto utile ed @`e piuttosto comoda +anche nei programmi @command{awk}. Di seguito si riporta una versione +@command{awk} di @code{getopt()}. Questa funzione mette in evidenza uno dei +maggiori punti deboli di @command{awk}, che @`e quello di essere molto carente +nella manipolazione di caratteri singoli. Sono necessarie ripetute chiamate a +@code{substr()} per accedere a caratteri singoli. +(@pxref{Funzioni per stringhe}).@footnote{Questa funzione +@`e stata scritta prima che @command{gawk} acquisisse la capacit@`a di +dividere le stringhe in caratteri singoli usando @code{""} come separatore. +@`E stata lasciata cos@`{@dotless{i}}, poich@'e l'uso di @code{substr()} @`e pi@`u portabile.} + +La spiegazione della funzione viene data +man mano che si elencano i pezzi di codice che la compongono: + +@cindex @code{getopt()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{getopt()} +@example +@c file eg/lib/getopt.awk +# getopt.awk --- imita in awk la funzione di libreria C getopt(3) +@c endfile +@ignore +@c file eg/lib/getopt.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# +# Initial version: March, 1991 +# Revised: May, 1993 +@c endfile +@end ignore +@c file eg/lib/getopt.awk + +# Variabili esterne: +# Optind -- indice in ARGV del primo argomento che non @`e un'opzione +# Optarg -- valore di tipo stringa dell'argomento dell'opzione corrente +# Opterr -- se diverso da zero, viene stampato un messaggio diagnostico +# Optopt -- lettera dell'opzione corrente + +# Restituisce: +# -1 alla fine delle opzioni +# "?" per un'opzione non riconosciuta +# <c> un carattere che rappresenta l'opzione corrente + +# Dati privati: +# _opti -- indice in un'opzione multipla, p.es., -abc +@c endfile +@end example + +La funzione inizia con commenti che elencano e descrivono le variabili globali +utilizzate, spiegano quali sono i valori di ritorno, il loro significato, e +ogni altra variabile che @`e +``esclusiva'' a questa funzione di libreria. Tale +documentazione @`e essenziale per qualsiasi programma, e in modo particolare per +le funzioni di libreria. + +La funzione @code{getopt()} dapprima controlla che sia stata effettivamente +chiamata con una stringa di opzioni (il parametro @code{opzioni}). Se +@code{opzioni} ha lunghezza zero, @code{getopt()} restituisce immediatamente +@minus{}1: + +@cindex @code{getopt()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{getopt()} +@example +@c file eg/lib/getopt.awk +function getopt(argc, argv, opzioni, unaopz, i) +@{ + if (length(opzioni) == 0) # nessuna opzione specificata + return -1 + +@group + if (argv[Optind] == "--") @{ # fatto tutto + Optind++ + _opti = 0 + return -1 +@end group + @} else if (argv[Optind] !~ /^-[^:[:space:]]/) @{ + _opti = 0 + return -1 + @} +@c endfile +@end example + +Il successivo controllo cerca la fine delle opzioni. Due trattini +(@option{--}) marcano la fine delle opzioni da riga di comando, e lo stesso +fa qualsiasi +argomento sulla riga di comando che non inizi con @samp{-}. @code{Optind} @`e +usato per scorrere il vettore degli argomenti presenti sulla riga di comando; +mantiene il suo valore attraverso chiamate successive a @code{getopt()}, perch@'e +@`e una variabile globale. + +L'espressione regolare che viene usata, @code{@w{/^-[^:[:space:]/}}, +chiede di cercare un +@samp{-} seguito da qualsiasi cosa che non sia uno spazio vuoto o un carattere +di due punti. Se l'argomento corrente sulla riga di comando non corrisponde a +quest'espressione regolare, vuol dire che non si tratta di un'opzione, e +quindi viene terminata l'elaborazione delle opzioni. Continuando: + +@example +@c file eg/lib/getopt.awk + if (_opti == 0) + _opti = 2 + unaopz = substr(argv[Optind], _opti, 1) + Optopt = unaopz + i = index(opzioni, unaopz) + if (i == 0) @{ + if (Opterr) + printf("%c -- opzione non ammessa\n", unaopz) > "/dev/stderr" + if (_opti >= length(argv[Optind])) @{ + Optind++ + _opti = 0 + @} else + _opti++ + return "?" + @} +@c endfile +@end example + +La variabile @code{_opti} tiene traccia della posizione nell'argomento +della riga di comando correntemente in esame +(@code{argv[Optind]}). Se opzioni multiple sono +raggruppate con un @samp{-} (p.es., @option{-abx}), @`e necessario +restituirle all'utente una per volta. + +Se @code{_opti} @`e uguale a zero, viene impostato a due, ossia all'indice +nella +stringa del successivo carattere da esaminare (@samp{-}, che @`e alla +posizione uno viene ignorato). +La variabile @code{unaopz} contiene il carattere, +ottenuto con @code{substr()}. Questo @`e salvato in @code{Optopt} per essere +usato dal programma principale. + +Se @code{unaopz} non @`e nella stringa delle opzioni @code{opzioni}, +si tratta di un'opzione +non valida. Se @code{Opterr} @`e diverso da zero, @code{getopt()} stampa un +messaggio di errore sullo @dfn{standard error} che @`e simile al messaggio +emesso dalla versione C di @code{getopt()}. + +Poich@'e l'opzione non @`e valida, @`e necessario tralasciarla e passare al successivo +carattere di opzione. Se @code{_opti} @`e maggiore o uguale alla lunghezza +dell'argomento corrente della riga di comando, @`e necessario passare al +successivo argomento, in modo che @code{Optind} venga incrementato e +@code{_opti} sia reimpostato a zero. In caso contrario, @code{Optind} viene +lasciato com'@`e e @code{_opti} viene soltanto incrementato. + +In ogni caso, poich@'e l'opzione non @`e valida, @code{getopt()} restituisce +@code{"?"}. Il programma principale pu@`o esaminare @code{Optopt} se serve +conoscere quale lettera di opzione @`e quella non valida. Proseguendo: + +@example +@c file eg/lib/getopt.awk + if (substr(opzioni, i + 1, 1) == ":") @{ + # ottiene un argomento di opzione + if (length(substr(argv[Optind], _opti + 1)) > 0) + Optarg = substr(argv[Optind], _opti + 1) + else + Optarg = argv[++Optind] + _opti = 0 + @} else + Optarg = "" +@c endfile +@end example + +Se l'opzione richiede un argomento, la lettera di opzione @`e seguita da due punti +nella stringa @code{opzioni}. Se rimangono altri caratteri nell'argomento +corrente sulla riga di comando (@code{argv[Optind]}), il resto di quella stringa +viene assegnato a @code{Optarg}. Altrimenti, viene usato il successivo +argomento sulla riga di comando (@samp{-xFOO} piuttosto che +@samp{@w{-x FOO}}). In +entrambi i casi, @code{_opti} viene reimpostato a zero, perch@'e non ci sono altri +caratteri da esaminare nell'argomento corrente sulla riga di comando. +Continuando: + +@example +@c file eg/lib/getopt.awk + if (_opti == 0 || _opti >= length(argv[Optind])) @{ + Optind++ + _opti = 0 + @} else + _opti++ + return unaopz +@} +@c endfile +@end example + +Infine, se @code{_opti} @`e zero o maggiore della lunghezza dell'argomento +corrente sulla riga di comando, significa che l'elaborazione di +quest'elemento in @code{argv} @`e +terminata, quindi @code{Optind} @`e incrementato per +puntare al successivo elemento in @code{argv}. Se nessuna delle condizioni @`e +vera, viene incrementato solo @code{_opti}, cosicch@'e la successiva lettera di +opzione pu@`o essere elaborata con la successiva chiamata a @code{getopt()}. + +La regola @code{BEGIN} inizializza sia @code{Opterr} che @code{Optind} a uno. +@code{Opterr} viene impostato a uno, perch@'e il comportamento di default per +@code{getopt()} @`e quello di stampare un messaggio diagnostico dopo aver visto +un'opzione non valida. @code{Optind} @`e impostato a uno, perch@'e non +c'@`e alcun motivo +per considerare il nome del programma, che @`e in @code{ARGV[0]}: + +@example +@c file eg/lib/getopt.awk +BEGIN @{ + Opterr = 1 # il default @`e eseguire una diagnosi + Optind = 1 # salta ARGV[0] + + # programma di controllo + if (_getopt_test) @{ + while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1) + printf("c = <%c>, Optarg = <%s>\n", + _go_c, Optarg) + printf("argomenti che non sono opzioni:\n") + for (; Optind < ARGC; Optind++) + printf("\tARGV[%d] = <%s>\n", + Optind, ARGV[Optind]) + @} +@} +@c endfile +@end example + +Il resto della regola @code{BEGIN} @`e un semplice programma di controllo. Qui +sotto si riportano i risultati di +due esecuzioni di prova +del programma di controllo: + +@example +$ @kbd{awk -f getopt.awk -v _getopt_test=1 -- -a -cbARG bax -x} +@print{} c = <a>, Optarg = <> +@print{} c = <c>, Optarg = <> +@print{} c = <b>, Optarg = <ARG> +@print{} argomenti che non sono opzioni: +@print{} ARGV[3] = <bax> +@print{} ARGV[4] = <-x> + +$ @kbd{awk -f getopt.awk -v _getopt_test=1 -- -a -x -- xyz abc} +@print{} c = <a>, Optarg = <> +@error{} x -- opzione non ammessa +@print{} c = <?>, Optarg = <> +@print{} argomenti che non sono opzioni: +@print{} ARGV[4] = <xyz> +@print{} ARGV[5] = <abc> +@end example + +In entrambe le esecuzioni, il primo @option{--} fa terminare gli argomenti dati +ad @command{awk}, in modo che @command{awk} non tenti di interpretare le opzioni +@option{-a}, etc. come sue opzioni. + +@quotation NOTA +Dopo che @code{getopt()} @`e terminato, +il codice a livello utente deve eliminare tutti gli elementi +di @code{ARGV} da +1 a @code{Optind}, in modo che @command{awk} non tenti di elaborare le opzioni +sulla riga di comando come @value{FNS}. +@end quotation + +Usare @samp{#!} con l'opzione @option{-E} pu@`o essere d'aiuto per evitare +conflitti tra le opzioni del proprio programma e quelle di @command{gawk}, +poich@'e l'opzione @option{-E} fa s@`{@dotless{i}} che @command{gawk} abbandoni +l'elaborazione di ulteriori opzioni. +(@pxref{@dfn{Script} eseguibili} e +@ifnotdocbook +@pxref{Opzioni}). +@end ifnotdocbook +@ifdocbook +@ref{Opzioni}). +@end ifdocbook + +Molti degli esempi presentati in +@ref{Programmi di esempio}, +usano @code{getopt()} per elaborare i propri argomenti. + +@node Funzioni Passwd +@section Leggere la lista degli utenti + +@cindex libreria di funzioni @command{awk}, leggere la lista degli utenti +@cindex funzioni, libreria di, leggera la lista degli utenti +@cindex utenti, leggere la lista degli +@cindex lista degli utenti@comma{} leggere la +@cindex @code{PROCINFO}, vettore +@cindex vettore @code{PROCINFO} +Il vettore @code{PROCINFO} +(@pxref{Variabili predefinite}) +d@`a accesso ai numeri ID reale ed effettivo dell'utente e del gruppo e, se +disponibili, alla serie di gruppi ulteriori a cui l'utente appartiene. +Comunque, poich@'e questi sono numeri, non forniscono informazioni molto utili per +l'utente medio. Bisogna trovare un modo per reperire informazioni +sull'utente associate con i numeri ID dell'utente e del gruppo. Questa +@value{SECTION} illustra una raccolta di funzioni per ottenere le informazioni +dalla lista gli utenti. @xref{Funzioni Group} per una raccolta di +funzioni simili per ottenere informazioni dalla lista dei gruppi. + +@cindex @code{getpwent()}, funzione (libreria C) +@cindex funzione @code{getpwent()} (libreria C) +@cindex @code{getpwent()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{getpwent()} +@cindex utenti, informazioni riguardo agli, ottenere +@cindex login, informazioni +@cindex account, informazioni sugli +@cindex password, file delle +@cindex file delle password +Lo standard POSIX non definisce il file dove sono mantenute le informazioni +degli utenti. Invece, fornisce il file d'intestazione @code{<pwd.h>} +e diverse @dfn{subroutine} del linguaggio C per ottenere informazioni sugli +utenti. La funzione primaria @`e @code{getpwent()}, che sta per ``get password +entry''. La ``password'' proviene dal file originale della lista +degli utenti, @file{/etc/passwd}, che contiene le informazioni sugli utenti +assieme alle password criptate (da cui il nome).@footnote{Questo @`e +vero per le versioni pi@`u antiche di Unix. In quelle pi@`u recenti, +la @dfn{password} di ogni utente @`e stata trasferita nel file @file{/etc/shadow}, +un file non accessibile dall'utente normale. La struttura del file +@file{/etc/passwd} @`e rimasta la stessa, ma al posto del campo @dfn{password} +c'@`e una @code{x}.} + +@cindex @command{pwcat}, programma +Sebbene un programma @command{awk} possa semplicemente leggere +@file{/etc/passwd} direttamente, questo file pu@`o non contenere tutte le +informazioni su tutti gli utenti del sistema.@footnote{Capita spesso che le +informazioni sulla password siano memorizzate in una lista in rete.} Per +essere sicuri di poter produrre una versione leggibile e completa della banca +dati degli utenti, @`e necessario scrivere un piccolo programma in C che chiama +@code{getpwent()}. @code{getpwent()} viene definita in modo da restituire un +puntatore a una @code{struct passwd}. Ogni volta che viene chiamata, +restituisce l'elemento successivo della lista. Quando non ci sono pi@`u +elementi, restituisce @code{NULL}, il puntatore nullo. Quando accade ci@`o, il +programma C dovrebbe chiamare @code{endpwent()} per chiudere la lista.. +Quel che segue @`e @command{pwcat}, un programma in C che ``concatena'' la +lista delle password: + +@example +@c file eg/lib/pwcat.c +/* + * pwcat.c + * + * Genera una versione stampabile della lista delle password. + */ +@c endfile +@ignore +@c file eg/lib/pwcat.c +/* + * Arnold Robbins, arnold@@skeeve.com, May 1993 + * Public Domain + * December 2010, move to ANSI C definition for main(). + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +@c endfile +@end ignore +@c file eg/lib/pwcat.c +#include <stdio.h> +#include <pwd.h> + +@c endfile +@ignore +@c file eg/lib/pwcat.c +#if defined (STDC_HEADERS) +#include <stdlib.h> +#endif + +@c endfile +@end ignore +@c file eg/lib/pwcat.c +int +main(int argc, char **argv) +@{ + struct passwd *p; + + while ((p = getpwent()) != NULL) +@c endfile +@ignore +@c file eg/lib/pwcat.c +#ifdef ZOS_USS + printf("%s:%ld:%ld:%s:%s\n", + p->pw_name, (long) p->pw_uid, + (long) p->pw_gid, p->pw_dir, p->pw_shell); +#else +@c endfile +@end ignore +@c file eg/lib/pwcat.c + printf("%s:%s:%ld:%ld:%s:%s:%s\n", + p->pw_name, p->pw_passwd, (long) p->pw_uid, + (long) p->pw_gid, p->pw_gecos, p->pw_dir, p->pw_shell); +@c endfile +@ignore +@c file eg/lib/pwcat.c +#endif +@c endfile +@end ignore +@c file eg/lib/pwcat.c + + endpwent(); + return 0; +@} +@c endfile +@end example + +Se non si conosce il linguaggio C, non @`e il caso di preoccuparsi. +L'output di @command{pwcat} @`e la lista degli utenti, nel formato +tradizionale del file @file{/etc/passwd} con campi separati da due punti. +I campi sono: + +@table @asis +@item Login name +Il nome di login dell'utente. + +@item Encrypted password +La password criptata dell'utente. Pu@`o non essere disponibile su alcuni sistemi. + +@item User-ID +L'ID numerico dell'utente. +(Su alcuni sistemi, @`e un numero di formato @code{long} [32bit] +del linguaggio C, e non nel formato @code{int} [16bit]. +Quindi, lo cambieremo in @code{long} per sicurezza.) + +@item Group-ID +L'ID di gruppo numerico dell'utente. +(Valgono le stesse considerazioni su @code{long} al posto di @code{int}.) + +@item Full name +Il nome completo dell'utente, e talora altre informazioni associate +all'utente. + +@item Home directory +La directory di login (o ``home'') (nota ai programmatori di shell come +@code{$HOME}). + +@item Login shell +Il programma che viene eseguito quando l'utente effettua l'accesso. Questo @`e +comunemente una shell, come Bash. +@end table + +Di seguito si riportano alcune righe di un possibile output di @command{pwcat}: + +@cindex Jacobs, Andrew +@cindex Robbins, Arnold +@cindex Robbins, Miriam +@example +$ @kbd{pwcat} +@print{} root:x:0:1:Operator:/:/bin/sh +@print{} nobody:x:65534:65534::/: +@print{} daemon:x:1:1::/: +@print{} sys:x:2:2::/:/bin/csh +@print{} bin:x:3:3::/bin: +@print{} arnold:x:2076:10:Arnold Robbins:/home/arnold:/bin/sh +@print{} miriam:x:112:10:Miriam Robbins:/home/miriam:/bin/sh +@print{} andy:x:113:10:Andy Jacobs:/home/andy:/bin/sh +@dots{} +@end example + +Dopo quest'introduzione, di seguito si riporta un gruppo di funzioni per +ottenere informazioni sugli utenti. Ci sono diverse funzioni, che +corrispondono alle omonime funzioni C: + +@cindex @code{_pw_init()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{_pw_init()} +@example +@c file eg/lib/passwdawk.in +# passwd.awk --- accedere alle informazioni del file delle password +@c endfile +@ignore +@c file eg/lib/passwdawk.in +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# May 1993 +# Revised October 2000 +# Revised December 2010 +@c endfile +@end ignore +@c file eg/lib/passwdawk.in + +BEGIN @{ + # modificare per adattarlo al sistema in uso + _pw_awklib = "/usr/local/libexec/awk/" +@} + +function _pw_init( oldfs, oldrs, olddol0, pwcat, using_fw, using_fpat) +@{ + if (_pw_inizializzato) + return + + oldfs = FS + oldrs = RS + olddol0 = $0 + using_fw = (PROCINFO["FS"] == "FIELDWIDTHS") + using_fpat = (PROCINFO["FS"] == "FPAT") + FS = ":" + RS = "\n" + + pwcat = _pw_awklib "pwcat" + while ((pwcat | getline) > 0) @{ + _pw_byname[$1] = $0 + _pw_byuid[$3] = $0 + _pw_bycount[++_pw_totale] = $0 + @} + close(pwcat) + _pw_contatore = 0 + _pw_inizializzato = 1 + FS = oldfs + if (using_fw) + FIELDWIDTHS = FIELDWIDTHS + else if (using_fpat) + FPAT = FPAT + RS = oldrs + $0 = olddol0 +@} +@c endfile +@end example + +@cindex @code{BEGIN}, criterio di ricerca, programma @code{pwcat} +@cindex criterio di ricerca @code{BEGIN}, programma @code{pwcat} +La regola @code{BEGIN} imposta una variabile privata col nome +della directory in cui si +trova @command{pwcat}. +Poich@'e @`e destinata a essere usata da una routine di +libreria di @command{awk}, si @`e scelto di metterla in +@file{/usr/local/libexec/awk}; comunque, in un altro sistema potrebbe +essere messa in una directory differente. + +La funzione @code{_pw_init()} mette tre copie delle informazioni sull'utente in +tre vettori associativi. I vettori sono indicizzati per nome-utente +(@code{_pw_byname}), per numero di ID-utente (@code{_pw_byuid}), e per ordine di +occorrenza (@code{_pw_bycount}). +La variabile @code{_pw_inizializzato} @`e usata per +efficienza, poich@'e in questo modo @code{_pw_init()} +viene chiamata solo una volta. + +@cindex @code{PROCINFO}, vettore, verificare la divisione in campi +@cindex vettore @code{PROCINFO}, verificare la divisione in campi +@cindex @code{getline}, comando, funzione definita dall'utente, @code{_pw_init()} +@cindex comando @code{getline}, funzione definita dall'utente, @code{_pw_init()} +Poich@'e questa funzione usa @code{getline} per leggere informazioni da +@command{pwcat}, dapprima salva i valori di @code{FS}, @code{RS} e @code{$0}. +Annota nella variabile @code{using_fw} se la suddivisione in campi +usando @code{FIELDWIDTHS} @`e attiva o no. +Far questo @`e necessario, poich@'e queste funzioni potrebbero essere chiamate da +qualsiai parte all'interno di un programma dell'utente, e l'utente pu@`o +suddividere i record in campi a suo piacimento. +Ci@`o rende possibile ripristinare il corretto meccanismo di suddivisione dei +campi in un secondo momento. La verifica pu@`o restituire solo @dfn{vero} per +@command{gawk}. +Il risultato pu@`o essere @dfn{falso} se si usa +@code{FS} o @code{FPAT}, +o in qualche altra implementazione di @command{awk}. + +Il codice che controlla se si sta usando @code{FPAT}, utilizzando +@code{using_fpat} e @code{PROCINFO["FS"]}, @`e simile. + +La parte principale della funzione usa un ciclo per leggere le righe della +lista, suddividere le righe in campi, e poi memorizzare la riga +all'interno di ogni vettore a seconda delle necessit@`a. Quando il ciclo @`e +completato, @code{@w{_pw_init()}} fa pulizia chiudendo la @dfn{pipe}, +impostando @code{@w{_pw_inizializzato}} a uno, e ripristinando @code{FS} +(e @code{FIELDWIDTHS} o @code{FPAT} +se necessario), @code{RS} e @code{$0}. +L'uso di @code{@w{_pw_contatore}} verr@`a spiegato a breve. + +@cindex @code{getpwnam()}, funzione (libreria C) +@cindex funzione @code{getpwnam()} (libreria C) +La funzione @code{getpwnam()} ha un nome utente come argomento di tipo +stringa. Se +quell'utente @`e presente nella lista, restituisce la riga appropriata. +Altrimenti, il riferimento a un elemento inesistente del vettore +aggiunge al vettore stesso un elemento il cui valore @`e la stringa nulla: + +@cindex @code{getpwnam()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{getpwnam()} +@example +@group +@c file eg/lib/passwdawk.in +function getpwnam(nome) +@{ + _pw_init() + return _pw_byname[nome] +@} +@c endfile +@end group +@end example + +@cindex @code{getpwuid()}, funzione (libreria C) +@cindex funzione @code{getpwuid()} (libreria C) +In modo simile, la funzione @code{getpwuid()} ha per argomento +il numero ID di un utente. +Se un utente con quel numero si trova nella lista, restituisce la riga +appropriata. Altrimenti restituisce la stringa nulla: + +@cindex @code{getpwuid()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{getpwuid()} +@example +@c file eg/lib/passwdawk.in +function getpwuid(uid) +@{ + _pw_init() + return _pw_byuid[uid] +@} +@c endfile +@end example + +@cindex @code{getpwent()}, funzione (libreria C) +@cindex funzione @code{getpwent()} (libreria C) +La funzione @code{getpwent()} scorre semplicemnte la lista, un elemento +alla volta. Usa @code{_pw_contatore} per tener traccia della posizione corrente +nel vettore @code{_pw_bycount}: + +@cindex @code{getpwent()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{getpwent()} +@example +@c file eg/lib/passwdawk.in +function getpwent() +@{ + _pw_init() + if (_pw_contatore < _pw_totale) + return _pw_bycount[++_pw_contatore] + return "" +@} +@c endfile +@end example + +@cindex @code{endpwent()}, funzione (libreria C) +@cindex funzione @code{endpwent()} (libreria C) +La funzione @code{@w{endpwent()}} reimposta @code{@w{_pw_contatore}} a zero, +in modo che chiamate successive a @code{getpwent()} ricomincino da capo: + +@cindex @code{endpwent()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{endpwent()} +@example +@c file eg/lib/passwdawk.in +function endpwent() +@{ + _pw_contatore = 0 +@} +@c endfile +@end example + +In questa serie di funzioni, il fatto che ogni subroutine chiami +@code{@w{_pw_init()}} +per inizializzare il vettore della lista utenti risponde a una precisa +scelta progettuale. +Il lavoro necessario per eseguire un processo separato che generi la +lista degli utenti, e l'I/O per esaminarla, si ha solo se il programma +principale dell'utente chiama effettivamente una di queste funzioni. +Se questo +file di libreria viene caricato assieme a un programma dell'utente, ma non +viene mai chiamata nessuna delle routine, non c'@`e nessun lavoro aggiuntivo +richiesto in fase di esecuzione. +(L'alternativa @`e quella di spostare il corpo di @code{@w{_pw_init()}} +all'interno di una regola @code{BEGIN}, che esegua sempre @command{pwcat}. +Questo semplifica il codice ma richiede di eseguire un processo extra +il cui risultato potrebbe non essere mai utilizzato dal programma.) + +A sua volta, chiamare ripetutamente @code{_pw_init()} non @`e troppo +dispendioso, perch@'e la +variabile @code{_pw_inizializzato} permette di evitare di leggere +i dati relativi agli utenti pi@`u di una +volta. Se la preoccupazione @`e quella di minimizzare il tempo di +esecuzione del programma @command{awk}, +il controllo di @code{_pw_inizializzato} potrebbe essere spostato +al di fuori di @code{_pw_init()} e duplicato in tutte le altre funzioni. +In pratica, questo non @`e necessario, poich@'e la maggior parte dei +programmi di @command{awk} +@`e I/O-bound@footnote{I programmi si distinguono tradizionalemente in +CPU-bound e I/O-bound. Quelli CPU-bound effettuano elaborazioni che non +richiedono molta attivit@`a di I/O, come ad esempio la preparazione di una +tavola di numeri primi. Quelli I/O bound leggono dei file, ma richiedono +poca attivit@`a di elaborazione per ogni record letto.}, +e una tale modifica complicherebbe inutilmente il codice. + +Il programma @command{id} in @ref{Programma id} +usa queste funzioni. + +@node Funzioni Group +@section Leggere la lista dei gruppi + +@cindex libreria di funzioni @command{awk}, leggere la lista dei gruppi +@cindex funzioni, libreria di, leggere la lista dei gruppi +@cindex gruppi, lista dei, leggere la +@cindex lista dei gruppi, leggere la +@cindex @code{PROCINFO}, vettore, e appartenenza a gruppi +@cindex @code{getgrent()}, funzione (libreria C) +@cindex funzione @code{getgrent()} (libreria C) +@cindex @code{getgrent()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{getgrent()} +@cindex gruppi@comma{} informazioni su +@cindex account, informazioni sugli +@cindex gruppi, file dei +@cindex file dei gruppi +Molto di quel che @`e stato detto +@iftex +nella +@end iftex +@ifnottex +in +@end ifnottex +@ref{Funzioni Passwd} +vale anche per la lista dei gruppi. Sebbene questa sia tradizionalmente +contenuta in +un file ben noto (@file{/etc/group}) in un altrettanto noto formato, +lo standard +POSIX prevede solo una serie di routine della libreria C +(@code{<grp.h>} e @code{getgrent()}) +per accedere a tali informazioni. +Anche se il file suddetto @`e disponibile, potrebbe non contenere delle +informazioni +complete. Perci@`o, come per la lista degli utenti, @`e necessario avere un +piccolo programma in C che genera la lista dei gruppi come suo output. +@command{grcat}, un programma in C che fornisce la lista dei gruppi, +@`e il seguente: + +@cindex @command{grcat}, programma C +@cindex programma C, @command{grcat} +@example +@c file eg/lib/grcat.c +/* + * grcat.c + * + * Genera una versione stampabile della lista dei gruppi. + */ +@c endfile +@ignore +@c file eg/lib/grcat.c +/* + * Arnold Robbins, arnold@@skeeve.com, May 1993 + * Public Domain + * December 2010, move to ANSI C definition for main(). + */ + +/* Per OS/2, non fare nulla. */ +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#if defined (STDC_HEADERS) +#include <stdlib.h> +#endif + +#ifndef HAVE_GETGRENT +int main() { return 0; } +#else +@c endfile +@end ignore +@c file eg/lib/grcat.c +#include <stdio.h> +#include <grp.h> + +int +main(int argc, char **argv) +@{ + struct group *g; + int i; + + while ((g = getgrent()) != NULL) @{ +@c endfile +@ignore +@c file eg/lib/grcat.c +#ifdef ZOS_USS + printf("%s:%ld:", g->gr_name, (long) g->gr_gid); +#else +@c endfile +@end ignore +@c file eg/lib/grcat.c + printf("%s:%s:%ld:", g->gr_name, g->gr_passwd, + (long) g->gr_gid); +@c endfile +@ignore +@c file eg/lib/grcat.c +#else + printf("%s:*:%ld:", g->gr_name, (long) g->gr_gid); +#endif +@c endfile +@end ignore +@c file eg/lib/grcat.c + for (i = 0; g->gr_mem[i] != NULL; i++) @{ + printf("%s", g->gr_mem[i]); +@group + if (g->gr_mem[i+1] != NULL) + putchar(','); + @} +@end group + putchar('\n'); + @} + endgrent(); + return 0; +@} +@c endfile +@ignore +@c file eg/lib/grcat.c +#endif /* HAVE_GETGRENT */ +@c endfile +@end ignore +@end example + +Ciascuna riga nella lista dei gruppi rappresenta un gruppo. I campi sono +separati da due punti e rappresentano le seguenti informazioni: + +@table @asis +@item Nome del gruppo +Il nome del gruppo. + +@item Password del gruppo +La password del gruppo criptata. In pratica, questo campo non viene mai usato; +normalmente @`e vuoto o impostato a @samp{x}. + +@item Numero ID del gruppo +Il numero ID del gruppo in formato numerico; +l'associazione del nome al numero dev'essere univoca all'interno di questo file. +(Su alcuni sistemi, @`e un numero nel formato @code{long} [32bit] +del linguaggio C, e non nel formato @code{int} [16bit]. +Quindi, lo cambieremo in @code{long} per sicurezza.) + +@item Lista dei membri del gruppo +Una lista di nomi utente separati da virgole. +Questi utenti sono i membri del gruppo. +I sistemi Unix moderni consentono agli utenti di appartenere a +diversi gruppi simultaneamente. Se il sistema in uso @`e uno di questi, ci sono +elementi in @code{PROCINFO} che vanno da @code{"group1"} fino a +@code{"group@var{N}"} per quei numeri di ID di gruppo. +(Si noti che @code{PROCINFO} @`e un'estensione @command{gawk}; +@pxref{Variabili predefinite}.) +@end table + +Di seguito si riporta quel che @command{grcat} potrebbe produrre: + +@example +$ @kbd{grcat} +@print{} wheel:x:0:arnold +@print{} nogroup:x:65534: +@print{} daemon:x:1: +@print{} kmem:x:2: +@print{} staff:x:10:arnold,miriam,andy +@print{} other:x:20: +@dots{} +@end example + +Qui ci sono le funzioni per ottenere informazioni relative alla lista dei +gruppi. Ce ne sono diverse, costruite sul modello delle omonime funzioni della +libreria C: + +@cindex @code{getline}, comando, funzione definita dall'utente, @code{_gr_init()} +@cindex comando @code{getline}, funzione definita dall'utente, @code{_gr_init()} +@cindex @code{_gr_init()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{_gr_init()} +@example +@c file eg/lib/groupawk.in +# group.awk --- funzioni per il trattamento del file dei gruppi +@c endfile +@ignore +@c file eg/lib/groupawk.in +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# May 1993 +# Revised October 2000 +# Revised December 2010 +@c endfile +@end ignore +@c line break on _gr_init for smallbook +@c file eg/lib/groupawk.in + +BEGIN @{ + # Modificare in base alla struttura del proprio sistema + _gr_awklib = "/usr/local/libexec/awk/" +@} + +function _gr_init( oldfs, oldrs, olddol0, grcat, + using_fw, using_fpat, n, a, i) +@{ + if (_gr_inizializzato) + return + + oldfs = FS + oldrs = RS + olddol0 = $0 + using_fw = (PROCINFO["FS"] == "FIELDWIDTHS") + using_fpat = (PROCINFO["FS"] == "FPAT") + FS = ":" + RS = "\n" + + grcat = _gr_awklib "grcat" + while ((grcat | getline) > 0) @{ + if ($1 in _gr_byname) + _gr_byname[$1] = _gr_byname[$1] "," $4 + else + _gr_byname[$1] = $0 + if ($3 in _gr_bygid) + _gr_bygid[$3] = _gr_bygid[$3] "," $4 + else + _gr_bygid[$3] = $0 + + n = split($4, a, "[ \t]*,[ \t]*") + for (i = 1; i <= n; i++) + if (a[i] in _gr_groupsbyuser) + _gr_groupsbyuser[a[i]] = _gr_groupsbyuser[a[i]] " " $1 + else + _gr_groupsbyuser[a[i]] = $1 + + _gr_bycount[++_gr_contatore] = $0 + @} + close(grcat) + _gr_contatore = 0 + _gr_inizializzato++ + FS = oldfs + if (using_fw) + FIELDWIDTHS = FIELDWIDTHS + else if (using_fpat) + FPAT = FPAT + RS = oldrs + $0 = olddol0 +@} +@c endfile +@end example + +La regola @code{BEGIN} imposta una variabile privata con il nome della +directory in cui si trova @command{grcat}. +Poich@'e @`e destinata a essere usata da una routine di +libreria di @command{awk}, si @`e scelto di metterla in +@file{/usr/local/libexec/awk}; comunque, in un altro sistema potrebbe +essere messa in una directory differente. + +Queste routine seguono le stesse linee generali delle routine per formare la +lista degli utenti (@pxref{Funzioni Passwd}). +La variabile @code{@w{_gr_inizializzato}} @`e usata per +essere sicuri che la lista venga letta una volta sola. +La funzione @code{@w{_gr_init()}} dapprima salva @code{FS}, +@code{RS} e +@code{$0}, e poi imposta @code{FS} e @code{RS} ai valori da usare nel +passare in rassegna le informazioni di gruppo. Inoltre +viene annotato se si stanno usando @code{FIELDWIDTHS} o @code{FPAT}, per +poter poi +ripristinare il meccanismo di suddivisione in campi appropriato. + +Le informazioni sui gruppi sono memorizzate in diversi vettori associativi. +I vettori sono indicizzati per nome di gruppo (@code{@w{_gr_byname}}), per +numero ID del gruppo (@code{@w{_gr_bygid}}), e per posizione nella lista +(@code{@w{_gr_bycount}}). C'@`e un vettore aggiuntivo indicizzato per nome utente +(@code{@w{_gr_groupsbyuser}}), che @`e una lista, separata da spazi, dei +gruppi ai quali ciascun utente appartiene. + +Diversamente dalla lista degli utenti, @`e possibile avere pi@`u record +nella lista per lo stesso gruppo. Questo @`e frequente quando un gruppo ha +un gran numero di membri. Un paio di tali voci potrebbero essere come queste: + +@example +tvpeople:x:101:johnny,jay,arsenio +tvpeople:x:101:david,conan,tom,joan +@end example + +Per questo motivo, @code{_gr_init()} controlla se un nome di gruppo o un numero +di ID di gruppo @`e stato gi@`a visto. Se cos@`{@dotless{i}} fosse, i nomi utente vanno +semplicemente concatenati con la precedente lista di utenti.@footnote{C'@`e un +piccolo problema col codice appena illustrato. Supponiamo che la prima volta +non ci siano nomi. Questo codice aggiunge i nomi con una virgola iniziale. +Inoltre non controlla che ci sia un @code{$4}.} + +Infine, @code{_gr_init()} chiude la @dfn{pipe} a @command{grcat}, ripristina +@code{FS} (e @code{FIELDWIDTHS} o @code{FPAT}, se necessario), @code{RS} e +@code{$0}, inizializza @code{_gr_contatore} a zero +(per essere usato pi@`u tardi), e rende @code{_gr_inizializzato} diverso da zero. + +@cindex @code{getgrnam()}, funzione (libreria C) +@cindex funzione @code{getgrnam()} (libreria C) +La funzione @code{getgrnam()} ha come argomento un nome di gruppo, e se quel +gruppo esiste, viene restituito. + +Altrimenti, il riferimento a un elemento inesistente del vettore +aggiunge al vettore stesso un elemento il cui valore @`e la stringa nulla: + +@cindex @code{getgrnam()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{getgrnam()} +@example +@c file eg/lib/groupawk.in +function getgrnam(group) +@{ + _gr_init() + return _gr_byname[group] +@} +@c endfile +@end example + +@cindex @code{getgrgid()}, funzione (libreria C) +@cindex funzione @code{getgrgid()} (libreria C) +La funzione @code{getgrgid()} @`e simile; ha come argomento un numero ID di +gruppo e controlla le informazioni assiciate con quell'ID di gruppo: + +@cindex @code{getgrgid()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{getgrgid()} +@example +@c file eg/lib/groupawk.in +function getgrgid(gid) +@{ + _gr_init() + return _gr_bygid[gid] +@} +@c endfile +@end example + +@cindex @code{getgruser()}, funzione (libreria C) +@cindex funzione @code{getgruser()} (libreria C) +La funzione @code{getgruser()} non ha un equivalente in C. Ha come argomento un +nome-utente e restituisce l'elenco dei gruppi di cui l'utente @`e membro: + +@cindex @code{getgruser()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{getgruser()} +@example +@c file eg/lib/groupawk.in +function getgruser(user) +@{ + _gr_init() + return _gr_groupsbyuser[user] +@} +@c endfile +@end example + +@cindex @code{getgrent()}, funzione (libreria C) +@cindex funzione @code{getgrent()} (libreria C) +La funzione @code{getgrent()} scorre la lista un elemento alla volta. +Usa @code{_gr_contatore} per ricordare la posizione corrente nella lista: + +@cindex @code{getgrent()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{getgrent()} +@example +@c file eg/lib/groupawk.in +function getgrent() +@{ + _gr_init() + if (++_gr_contatore in _gr_bycount) + return _gr_bycount[_gr_contatore] + return "" +@} +@c endfile +@end example + +@cindex @code{endgrent()}, funzione (libreria C) +@cindex funzione @code{endgrent()} (libreria C) +La funzione @code{endgrent()} reimposta @code{_gr_contatore} a zero in modo che +@code{getgrent()} possa ricominciare da capo: + +@cindex @code{endgrent()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{endgrent()} +@example +@c file eg/lib/groupawk.in +function endgrent() +@{ + _gr_contatore = 0 +@} +@c endfile +@end example + +Come con le routine per la lista degli utenti, ogni funzione chiama +@code{_gr_init()} per inizializzare i vettori. +Cos@`{@dotless{i}} facendo si avr@`a il solo +lavoro aggiuntivo di eseguire @command{grcat} se queste funzioni vengono +usate (rispetto a spostare il corpo di @code{_gr_init()} all'interno della +regola @code{BEGIN}). + +La maggior parte del lavoro consiste nell'ispezionare la lista e nel +costruire i vari vettori associativi. Le funzioni che l'utente chiama sono +di per s@'e molto semplici, poich@'e si appoggiano sui vettori associativi di +@command{awk} per fare il lavoro. + +Il programma @command{id} in @ref{Programma id} +usa queste funzioni. + +@node Visitare vettori +@section Attraversare vettori di vettori + +@iftex +La +@end iftex +@ref{Vettori di vettori} trattava come @command{gawk} +avere a disposizione vettori di vettori. In particolare, qualsiasi elemento di +un vettore pu@`o essere uno scalare o un altro vettore. La funzione +@code{isarray()} (@pxref{Funzioni per i tipi}) +permette di distinguere un vettore +da uno scalare. +La seguente funzione, @code{walk_array()}, attraversa ricorsivamente +un vettore, stampando gli indici e i valori di ogni elemento. +Viene chiamata col vettore e con una stringa che contiene il nome +del vettore: + +@cindex @code{walk_array()}, funzione definita dall'utente +@cindex funzione definita dall'utente, @code{walk_array()} +@example +@c file eg/lib/walkarray.awk +function walk_array(vett, nome, i) +@{ + for (i in vett) @{ + if (isarray(vett[i])) + walk_array(vett[i], (nome "[" i "]")) + else + printf("%s[%s] = %s\n", nome, i, vett[i]) + @} +@} +@c endfile +@end example + +@noindent +Funziona eseguendo un ciclo su ogni elemento del vettore. Se un dato elemento +@`e esso stesso un vettore, la funzione chiama s@'e stessa ricorsivamente, +passando il sottovettore e una nuova stringa che rappresenta l'indice corrente. +In caso contrario, la funzione stampa semplicemente il nome, l'indice e il +valore dell'elemento. +Qui di seguito si riporta un programma principale che ne mostra l'uso: + +@example +BEGIN @{ + a[1] = 1 + a[2][1] = 21 + a[2][2] = 22 + a[3] = 3 + a[4][1][1] = 411 + a[4][2] = 42 + + walk_array(a, "a") +@} +@end example + +Quando viene eseguito, il programma produce il seguente output: + +@example +$ @kbd{gawk -f walk_array.awk} +@print{} a[1] = 1 +@print{} a[2][1] = 21 +@print{} a[2][2] = 22 +@print{} a[3] = 3 +@print{} a[4][1][1] = 411 +@print{} a[4][2] = 42 +@end example + +La funzione appena illustrata stampa semplicemente il nome e il valore +di ogni elemento costituito da un vettore scalare. Comunque @`e facile +generalizzarla, passandole il nome di una funzione da chiamare +quando si attraversa un vettore. La funzione modificata @`e simile a questa: + +@example +@c file eg/lib/processarray.awk +function process_array(vett, nome, elab, do_arrays, i, nuovo_nome) +@{ + for (i in vett) @{ + nuovo_nome = (nome "[" i "]") + if (isarray(vett[i])) @{ + if (do_arrays) + @@elab(nuovo_nome, vett[i]) + process_array(vett[i], nuovo_nome, elab, do_arrays) + @} else + @@elab(nuovo_nome, vett[i]) + @} +@} +@c endfile +@end example + +Gli argomenti sono i seguenti: + +@table @code +@item vett +Il vettore. + +@item nome +Il nome del vettore (una stringa). + +@item elab +Il nome della funzione da chiamare. + +@item do_arrays +Se vale @dfn{vero}, la funzione pu@`o gestire elementi che sono sottovettori. +@end table + +Se devono essere elaborati sottovettori, questo vien fatto prima di +attraversarne altri. + +Quando viene eseguita con la seguente struttura, la funzione produce lo stesso +risultato della precedente versione di @code{walk_array()}: + +@example +BEGIN @{ + a[1] = 1 + a[2][1] = 21 + a[2][2] = 22 + a[3] = 3 + a[4][1][1] = 411 + a[4][2] = 42 + + process_array(a, "a", "do_print", 0) +@} + +function do_print(nome, elemento) +@{ + printf "%s = %s\n", nome, elemento +@} +@end example + +@node Sommario funzioni di libreria +@section Riassunto + +@itemize @value{BULLET} +@item +Leggere i programmi @`e un eccellente metodo per imparare la "buona +programmazione". Le funzioni e i programmi contenuti in questo @value{CHAPTER} +e nel successivo si propongo questo obiettivo. + +@item +Quando si scrivono funzioni di libreria di uso generale, si deve stare attenti +ai nomi da dare alle variabili globali, facendo in modo che non entrino in +conflitto con le variabili di un programma dell'utente. + +@item +Le funzioni descritte qui appartengono alle seguenti categorie: + +@c nested list +@table @asis +@item Problemi generali +Conversione di numeri in stringhe, verifica delle asserzioni, arrotondamenti, +generazione di numeri casuali, conversione di caratteri in numeri, unione di +stringhe, ottenimento di informazioni su data e ora facilmente usabili, +e lettura di un intero file in una volta sola + +@item Gestione dei @value{DF} +Annotazione dei limiti di un @value{DF}, rilettura del file corrente, +ricerca di +file leggibili, ricerca di file di lunghezza zero, e trattamento degli +assegnamenti di variabili fatti sulla riga comando come @value{FNS} + +@item Elaborazione di opzioni sulla riga di comando +Una versione @command{awk} della funzione del C standard @code{getopt()} + +@item Lettura dei file degli utenti e dei gruppi +Due serie di routine equivalenti alle versioni disponibili nella libreria +del linguaggio C + +@item Attraversamento di vettori di vettori +Due funzioni che attraversano un vettore di vettori fino in fondo +@end table +@c end nested list + +@end itemize + +@c EXCLUDE START +@node Esercizi con le librerie +@section Esercizi + +@enumerate +@item +@iftex +Nella +@end iftex +@ifnottex +In +@end ifnottex +@ref{File vuoti}, abbiamo illustrato il programma @file{zerofile.awk}, +che fa uso della variabile di @command{gawk} @code{ARGIND}. Questo problema pu@`o +essere risolto senza dipendere da @code{ARGIND}? Se s@`{@dotless{i}}, come? + +@ignore +# zerofile2.awk --- same thing, portably + +BEGIN @{ + ARGIND = Argind = 0 + for (i = 1; i < ARGC; i++) + Fnames[ARGV[i]]++ + +@} +FNR == 1 @{ + while (ARGV[ARGIND] != FILENAME) + ARGIND++ + Seen[FILENAME]++ + if (Seen[FILENAME] == Fnames[FILENAME]) + do + ARGIND++ + while (ARGV[ARGIND] != FILENAME) +@} +ARGIND > Argind + 1 @{ + for (Argind++; Argind < ARGIND; Argind++) + zerofile(ARGV[Argind], Argind) +@} +ARGIND != Argind @{ + Argind = ARGIND +@} +END @{ + if (ARGIND < ARGC - 1) + ARGIND = ARGC - 1 + if (ARGIND > Argind) + for (Argind++; Argind <= ARGIND; Argind++) + zerofile(ARGV[Argind], Argind) +@} +@end ignore + +@item +Come esercizio collegato, rivedere quel codice per gestire il caso in cui un +valore contenuto in @code{ARGV} sia un assegnamento di variabile. + +@ignore +@c June 13 2015: Antonio points out that this is answered in the text. Ooops. +@item +@ref{Visitare vettori} ha illustrato una funzione che ispezionava un vettore +multidimensionale per stamparlo. Comunque, ispezionare un vettore ed elaborare +ogni elemento @`e un'operazione generica. Generalizzare la funzione +@code{walk_array()} agggiungendo un parametro aggiuntivo chiamato +@code{elab}. + +Quindi, all'interno del ciclo, invece di stampare l'indice e il valore +dell'elemento del vettore, usare la sintassi della chiamata indiretta a una +funzione (@pxref{Chiamate indirette}) +su @code{elab}, passandole l'indice e il valore. + +Nel chiamare @code{walk_array()}, si passa il nome di una +funzione definita dall'utente che aspetta di ricevere un indice e un valore +per poi elaborare l'elemento. + +Verificare la nuova versione stampando il vettore; si dovrebbe ottenere un +output identico a quello della versione originale. +@end ignore + +@end enumerate +@c EXCLUDE END + +@node Programmi di esempio +@chapter Programmi utili scritti in @command{awk} +@cindex @command{awk}, programmi, esempi di +@cindex programmi @command{awk}, esempi di +@cindex esempi di programmi @command{awk} + +@c FULLXREF ON +@iftex +Il +@end iftex +@ref{Funzioni di libreria}, +ha prospettato l'idea che la lettura di programmi scritti in un certo +linguaggio possa aiutare a imparare quel linguaggio. Questo +@value{CHAPTER} ripropone lo stesso tema, presentando una miscellanea di +programmi @command{awk} per il piacere di leggerli. +@c FULLXREF OFF +@ifnotinfo +Ci sono tre @value{SECTIONS}. +La prima spiega come eseguire i programmi descritti in questo +@value{CHAPTER}. + +La seconda illustra la versione @command{awk} +di parecchi comuni programmi di utilit@`a disponibili in POSIX. +Si presuppone che si abbia gi@`a una certa familiarit@`a con questi programmi, +e che quindi i problemi a loro legati siano facilmente comprensibili. +Riscrivendo questi programmi in @command{awk}, +ci si pu@`o focalizzare sulle particolarit@`a di @command{awk} nella +risoluzione dei problemi di programmazione. + +La terza sezione @`e una collezione di programmi interessanti. +Essi mirano a risolvere un certo numero di differenti problemi di +manipolazione e di gestione dati. Molti dei programmi sono brevi, per +evidenziare la capacit@`a di @command{awk} di fare molte cose usando solo +poche righe di codice. +@end ifnotinfo + +Molti di questi programmi usano le funzioni di libreria che sono state presentate +@iftex +nel +@end iftex +@ifnottex +in +@end ifnottex +@ref{Funzioni di libreria}. + +@menu +* Eseguire esempi:: Come eseguire questi esempi. +* Cloni:: Cloni di programmi di utilit@`a comuni. +* Programmi vari:: Alcuni interessanti programmi in + @command{awk}. +* Sommario dei programmi:: Sommario dei programmi. +* Esercizi sui programmi:: Esercizi. +@end menu + +@node Eseguire esempi +@section Come eseguire i programmi di esempio. + + +Per eseguire un dato programma, si procederebbe tipicamente cos@`{@dotless{i}}: + +@example +awk -f @var{programma} -- @var{opzioni} @var{file} +@end example + +@noindent +Qui, @var{programma} @`e il nome del programma @command{awk} (p.es. +@file{cut.awk}), @var{opzioni} sono le opzioni sulla riga di comando +per il programma che iniziano con un @samp{-}, e @var{file} sono i +@value{DF} in input. + +Se il sistema prevede il meccanismo @samp{#!} di specifica di un +@dfn{interprete} +(@pxref{@dfn{Script} eseguibili}), +si pu@`o invece eseguire direttamente un programma: + +@example +cut.awk -c1-8 i_miei_file > risultati +@end example + +Se @command{awk} non @`e @command{gawk}, pu@`o invece essere necessario usare: + +@example +cut.awk -- -c1-8 i_miei_file > risultati +@end example + +@node Cloni +@section Reinventare la ruota per divertimento e profitto +@cindex programmi POSIX, implementazione in @command{awk} +@cindex POSIX, programmi, implementazione in @command{awk} + +Questa @value{SECTION} presenta un certo numero di programmi di utilit@`a +POSIX implementati in @command{awk}. Riscrivere questi programmi in +@command{awk} @`e spesso divertente, +perch@'e gli algoritmi possono essere espressi molto chiaramente, e il codice +@`e normalmente molto semplice e conciso. Ci@`o @`e possibile perch@'e @command{awk} +facilita molto le cose al programmatore. + +Va precisato che questi programmi non sono necessariamente scritti per +sostituire le versioni installate sul sistema in uso. +Inoltre, nessuno di questi programmi @`e del tutto aderente ai pi@`u recenti +standard POSIX. Questo non @`e un problema; il loro scopo +@`e di illustrare la programmazione in linguaggio @command{awk} che serve nel +``mondo reale''. + +I programmi sono presentati in ordine alfabetico. + +@menu +* Programma cut:: Il programma di utilit@`a @command{cut}. +* Programma egrep:: Il programma di utilit@`a @command{egrep}. +* Programma id:: Il programma di utilit@`a @command{id}. +* Programma split:: Il programma di utilit@`a @command{split}. +* Programma tee:: Il programma di utilit@`a @command{tee}. +* Programma uniq:: Il programma di utilit@`a @command{uniq}. +* Programma wc:: Il programma di utilit@`a @command{wc}. +@end menu + +@node Programma cut +@subsection Ritagliare campi e colonne + +@cindex @command{cut}, programma di utilit@`a +@cindex programma di utilit@`a @command{cut} +@cindex campi, ritagliare +@cindex colonne, ritagliare +Il programma di utilit@`a @command{cut} seleziona, o ``taglia'' (@dfn{cut}), +caratteri o campi dal suo standard input e li +spedisce al suo standard output. +I campi sono separati da caratteri TAB per default, +ma @`e possibile fornire un'opzione dalla riga di comando per cambiare il campo +@dfn{delimitatore} (cio@`e, il carattere che separa i campi). La definizione di +campo di @command{cut} @`e meno generale di quella di @command{awk}. + +Un uso comune del comando @command{cut} potrebbe essere quello di estrarre +i nomi degli utenti correntemente collegati al sistema, a partire +dall'output del comando @command{who}. Per esempio, la seguente +pipeline genera una lista in ordine alfabetico, senza doppioni, degli utenti +correntemente collegati al sistema: + +@example +who | cut -c1-8 | sort | uniq +@end example + +Le opzioni per @command{cut} sono: + +@table @code +@item -c @var{lista} +Usare @var{lista} come lista di caratteri da ritagliare. Elementi +all'interno della lista +possono essere separati da virgole, e intervalli di caratteri possono essere +separated da trattini. La lista +@samp{1-8,15,22-35} specifica i caratteri da 1 a 8, 15, e da 22 a 35. + +@item -f @var{lista} +Usare @var{lista} come lista di campi da ritagliare. + +@item -d @var{delimitatore} +Usare @var{delimitatore} come carattere che separa i campi invece del +carattere TAB. + +@item -s +Evita la stampa di righe che non contengono il delimitatore di campo. +@end table + +L'implementazione @command{awk} del comando @command{cut} usa la funzione +di libreria @code{getopt()} +(@pxref{Funzione getopt}) +e la funzione di libreria @code{join()} +(@pxref{Funzione join}). + +Il programma inizia con un commento che descrive le opzioni, le funzioni +di libreria necessarie, e una funzione @code{sintassi()} che stampa un +messaggio ed esce. @code{sintassi()} @`e chiamato se si specificano degli +argomenti non validi: + +@cindex @code{cut.awk}, programma +@cindex programma @code{cut.awk} +@example +@c file eg/prog/cut.awk +# cut.awk --- implementa cut in awk +@c endfile +@ignore +@c file eg/prog/cut.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# May 1993 +@c endfile +@end ignore +@c file eg/prog/cut.awk + +# Opzioni: +# -f lista Ritagliare campi +# -d c Carattere di delimitazione di campo +# -c lista Ritagliare caratteri +# +# -s Sopprimere righe che non contengono il delimitatore +# +# Richiede le funzioni di libreria getopt() e join() + +@group +function sintassi() +@{ + print("sintassi: cut [-f lista] [-d c] [-s] [file...]") > "/dev/stderr" + print("sintassi: cut [-c lista] [file...]") > "/dev/stderr" + exit 1 +@} +@end group +@c endfile +@end example + +@cindex @code{BEGIN}, criterio di ricerca, eseguire programmi @command{awk} e +@cindex criterio di ricerca @code{BEGIN}, eseguire programmi @command{awk} e +@cindex @code{FS}, variabile, eseguire programmi @command{awk} e +@cindex variabile @code{FS}, eseguire programmi @command{awk} e +Subito dopo c'@`e una regola @code{BEGIN} che analizza le opzioni della riga +di comando. +Questa regola imposta @code{FS} a un solo carattere TAB, perch@'e quello @`e +il separatore di campo di @command{cut} per default. +La regola poi imposta il separatore di campo in output allo stesso valore +del separatore di campo in input. Un ciclo che usa @code{getopt()} esamina +le opzioni della riga di comando. Una e una sola delle variabili +@code{per_campi} o @code{per_caratteri} @`e impostata a "vero", per indicare +che l'elaborazione sar@`a fatta per campi o per caratteri, rispettivamente. +Quando si ritaglia per caratteri, il separatore di campo in output @`e +impostato alla stringa nulla: + +@example +@c file eg/prog/cut.awk +BEGIN @{ + FS = "\t" # default + OFS = FS + while ((c = getopt(ARGC, ARGV, "sf:c:d:")) != -1) @{ + if (c == "f") @{ + per_campi = 1 + lista_campi = Optarg + @} else if (c == "c") @{ + per_caratteri = 1 + lista_campi = Optarg + OFS = "" + @} else if (c == "d") @{ + if (length(Optarg) > 1) @{ + printf("cut: usa il primo carattere di %s" \ + " come delimitatore\n", Optarg) > "/dev/stderr" + Optarg = substr(Optarg, 1, 1) + @} + fs = FS = Optarg + OFS = FS + if (FS == " ") # mette specifica in formato awk + FS = "[ ]" + @} else if (c == "s") + sopprimi = 1 + else + sintassi() + @} + + # Toglie opzioni da riga di comando + for (i = 1; i < Optind; i++) + ARGV[i] = "" +@c endfile +@end example + +@cindex separatori di campo, spazi come +@cindex spazi come separatori di campo +Nella scrittura del codice si deve porre particolare attenzione quando il +delimitatore di campo @`e uno spazio. Usare +un semplice spazio (@code{@w{" "}}) come valore per @code{FS} @`e +sbagliato: @command{awk} separerebbe i campi con serie di spazi, +TAB, e/o ritorni a capo, mentre devono essere separati solo da uno spazio. +Per far questo, salviamo il carattere di spazio originale nella variabile +@code{fs} per un uso futuro; dopo aver impostato @code{FS} a @code{"[ ]"} non +@`e possibile usarlo direttamente per vedere se il carattere delimitatore di +campo @`e nella stringa. + +Si ricordi anche che dopo che si @`e finito di usare @code{getopt()} +(come descritto nella @ref{Funzione getopt}), +@`e necessario +eliminare tutti gli elementi del vettore @code{ARGV} da 1 a @code{Optind}, +in modo che @command{awk} non tenti di elaborare le opzioni della riga di comando +come @value{FNS}. + +Dopo aver elaborato le opzioni della riga di comando, il programma verifica +che le opzioni siano coerenti. Solo una tra le opzioni @option{-c} +e @option{-f} dovrebbe essere presente, ed entrambe richiedono una lista di +campi. Poi il programma chiama +@code{prepara_lista_campi()} oppure @code{prepara_lista_caratteri()} per +preparare la lista dei campi o dei caratteri: + +@example +@c file eg/prog/cut.awk + if (per_campi && per_caratteri) + sintassi() + + if (per_campi == 0 && per_caratteri == 0) + per_campi = 1 # default + + if (lista_campi == "") @{ + print "cut: specificare lista per -c o -f" > "/dev/stderr" + exit 1 + @} + + if (per_campi) + prepara_lista_campi() + else + prepara_lista_caratteri() +@} +@c endfile +@end example + +@code{prepara_lista_campi()} pone la lista campi, usando la virgola come +separatore, in un vettore. Poi, per +ogni elemento del vettore, controlla che esso non sia un intervallo. Se @`e +un intervallo, lo fa diventare un elenco. La funzione controlla l'intervallo +specificato, per assicurarsi che il primo numero sia minore del secondo. +Ogni numero nella lista @`e aggiunto al vettore @code{lista_c}, che +semplicemente elenca i campi che saranno stampati. Viene usata la normale +separazione in campi di @command{awk}. Il programma lascia ad @command{awk} +il compito di separare i campi: + +@example +@c file eg/prog/cut.awk +function prepara_lista_campi( n, m, i, j, k, f, g) +@{ + n = split(lista_campi, f, ",") + j = 1 # indice in lista_c + for (i = 1; i <= n; i++) @{ + if (index(f[i], "-") != 0) @{ # un intervallo + m = split(f[i], g, "-") +@group + if (m != 2 || g[1] >= g[2]) @{ + printf("cut: lista campi errata: %s\n", + f[i]) > "/dev/stderr" + exit 1 + @} +@end group + for (k = g[1]; k <= g[2]; k++) + lista_c[j++] = k + @} else + lista_c[j++] = f[i] + @} + ncampi = j - 1 +@} +@c endfile +@end example + +La funzione @code{prepara_lista_caratteri()} @`e pi@`u complicata di +@code{prepara_lista_campi()}. +L'idea qui @`e di usare la variabile di @command{gawk} @code{FIELDWIDTHS} +(@pxref{Dimensione costante}), +che descrive input a larghezza costante. Quando si usa una lista di +caratteri questo @`e proprio il nostro caso. + +Impostare @code{FIELDWIDTHS} @`e pi@`u complicato che semplicemente elencare +i campi da stampare. Si deve tener traccia dei campi da +stampare e anche dei caratteri che li separano, che vanno saltati. +Per esempio, supponiamo che si vogliano i caratteri da 1 a 8, 15, +e da 22 a 35. Per questo si specifica @samp{-c 1-8,15,22-35}. Il valore che +corrisponde a questo nella variabile @code{FIELDWIDTHS} @`e +@code{@w{"8 6 1 6 14"}}. Questi sono cinque campi, e quelli da stampare +sono @code{$1}, @code{$3}, e @code{$5}. +I campi intermedi sono @dfn{riempitivo} (@dfn{filler}), +ossia @`e ci@`o che separa i dati che si desidera estrarre. +@code{lista_c} lista i campi da stampare, e @code{t} traccia l'elenco +completo dei campi, inclusi i riempitivi: + +@example +@c file eg/prog/cut.awk +function prepara_lista_caratteri( campo, i, j, f, g, n, m, t, + filler, ultimo, lungo) +@{ + campo = 1 # contatore totale campi + n = split(lista_campi, f, ",") + j = 1 # indice in lista_c + for (i = 1; i <= n; i++) @{ + if (index(f[i], "-") != 0) @{ # intervallo + m = split(f[i], g, "-") + if (m != 2 || g[1] >= g[2]) @{ + printf("cut: lista caratteri errata: %s\n", + f[i]) > "/dev/stderr" + exit 1 + @} + lungo = g[2] - g[1] + 1 + if (g[1] > 1) # calcola lunghezza del riempitivo + filler = g[1] - ultimo - 1 + else + filler = 0 +@group + if (filler) + t[campo++] = filler +@end group + t[campo++] = lungo # lunghezza del campo + ultimo = g[2] + lista_c[j++] = campo - 1 + @} else @{ + if (f[i] > 1) + filler = f[i] - ultimo - 1 + else + filler = 0 + if (filler) + t[campo++] = filler + t[campo++] = 1 + ultimo = f[i] + lista_c[j++] = campo - 1 + @} + @} + FIELDWIDTHS = join(t, 1, campo - 1) + ncampi = j - 1 +@} +@c endfile +@end example + +Poi viene la regola che elabora i dati. Se l'opzione @option{-s} @`e stata +specificata, il flag @code{sopprimi} +@`e vero. La prima istruzione +@code{if} accerta che il record in input abbia il separatore di +campo. Se @command{cut} sta elaborando dei campi, e @code{sopprimi} @`e vero, +e il carattere di separazione dei campi non @`e presente nel record, il +record @`e ignorato. + +Se il record @`e valido, @command{gawk} ha gi@`a separato i dati in campi, +usando il carattere in @code{FS} o usando campi a lunghezza fissa +e @code{FIELDWIDTHS}. Il ciclo scorre attraverso la lista di campi che +si dovrebbero stampare. Il campo corrispondente @`e stampato se contiene dati. +Se il campo successivo contiene pure dei dati, il carattere di separazione @`e +scritto tra i due campi: + +@example +@c file eg/prog/cut.awk +@{ + if (per_campi && sopprimi && index($0, fs) == 0) + next + + for (i = 1; i <= ncampi; i++) @{ + if ($lista_c[i] != "") @{ + printf "%s", $lista_c[i] + if (i < ncampi && $lista_c[i+1] != "") + printf "%s", OFS + @} + @} + print "" +@} +@c endfile +@end example + +Questa versione di @command{cut} utilizza la variabile @code{FIELDWIDTHS} di +@command{gawk} per ritagliare in base alla posizione dei caratteri. @`E +possibile, in altre implementazioni di @command{awk} usare @code{substr()} +(@pxref{Funzioni per stringhe}), ma +la cosa @`e molto pi@`u complessa. +La variabile @code{FIELDWIDTHS} fornisce una soluzione elegante al problema +di suddividere la riga in input in singoli caratteri. + + +@node Programma egrep +@subsection Ricercare espressioni regolari nei file + +@cindex espressioni regolari, ricerca di +@cindex ricercare, in file, espressioni regolari +@cindex file, ricercare espressioni regolari nei +@cindex @command{egrep}, programma di utilit@`a +@cindex programma di utilit@`a @command{egrep} +Il programma di utilit@`a @command{egrep} ricerca occorrenze di espressioni +regolari all'interno di file. Usa +espressioni regolari che sono quasi identiche a quelle disponibili in +@iftex +@command{awk} (@pxrefil{Espressioni regolari}). +@end iftex +@ifnottex +@command{awk} (@pxref{Espressioni regolari}). +@end ifnottex +Si richiama cos@`{@dotless{i}}: + +@display +@command{egrep} [@var{opzioni}] @code{'@var{espressione}'} @var{file} @dots{} +@end display + +@var{espressione} @`e un'espressione regolare. Normalmente, l'espressione +regolare @`e protetta da apici per impedire alla shell di espandere ogni +carattere speciale come @value{FN}. +Normalmente, @command{egrep} stampa le righe per cui @`e stata trovata una +corrispondenza. Se nella riga di comando si richiede di operare su pi@`u di un +@value{FN}, ogni riga in output @`e preceduta dal nome del file, e dal segno +due punti. + +Le opzioni di @command{egrep} sono le seguenti: + +@table @code +@item -c +Stampa un contatore delle righe che corrispondono al criterio di ricerca, +e non le righe stesse. + +@item -s +Funziona in silenzio. Non si produce alcun output ma il codice di ritorno +indica se il criterio di ricerca ha trovato almeno una corrispondenza. + +@item -v +Inverte il senso del test. @command{egrep} stampa le righe che +@emph{non} soddisfano il criterio di ricerca ed esce con successo se il +criterio di ricerca non @`e soddisfatto. + +@item -i +Ignora maiuscolo/minuscolo sia nel criterio di ricerca che nei dati in input. + +@item -l +Stampa (elenca) solo i nomi dei file che corrispondono, e non le righe trovate. + +@item -e @var{espressione} +Usa @var{espressione} come @dfn{regexp} da ricercare. Il motivo per cui +@`e prevista l'opzione @option{-e} @`e di +permettere dei criteri di ricerca che +inizino con un @samp{-}. +@end table + +Questa versione usa la funzione di libreria @code{getopt()} +(@pxref{Funzione getopt}) +e il programma di libreria che gestisce il passaggio da un file dati +al successivo +(@pxref{Funzione filetrans}). + +Il programma inizia con un commento descrittivo e poi c'@`e una regola +@code{BEGIN} +che elabora gli argomenti della riga di comando usando @code{getopt()}. +L'opzione @option{-i} (ignora maiuscolo/minuscolo) @`e particolarmente facile +da implementare con @command{gawk}; basta usare la variabile predefinita +@code{IGNORECASE} +(@pxref{Variabili predefinite}): + +@cindex @code{egrep.awk}, programma +@cindex programma @code{egrep.awk} +@example +@c file eg/prog/egrep.awk +# egrep.awk --- simula egrep in awk +# +@c endfile +@ignore +@c file eg/prog/egrep.awk +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# May 1993 + +@c endfile +@end ignore +@c file eg/prog/egrep.awk +# Opzioni: +# -c conta le righe trovate +# -s sileziosa: genera solo il codice di ritorno +# -v inverte test, successo se @dfn{regexp} non presente +# -i ignora maiuscolo/minuscolo +# -l stampa solo nomi file +# -e espressione da ricercare +# +# Richiede la funzione getopt() e il programma di libreria +# che gestisce il passaggio da un file dati al successivo + +BEGIN @{ + while ((c = getopt(ARGC, ARGV, "ce:svil")) != -1) @{ + if (c == "c") + conta_e_basta++ + else if (c == "s") + non_stampare++ + else if (c == "v") + inverti_test++ + else if (c == "i") + IGNORECASE = 1 + else if (c == "l") + solo_nomi_file++ + else if (c == "e") + criterio_di_ricerca = Optarg + else + sintassi() + @} +@c endfile +@end example + +Nel seguito c'@`e il codice che gestisce il comportamento specifico di +@command{egrep}. Se non @`e fornito esplicitamente alcun criterio di ricerca +tramite l'opzione @option{-e}, si usa il primo argomento sulla riga di +comando che non sia un'opzione. +Gli argomenti della riga di comando di @command{awk} fino ad +@code{ARGV[Optind]} vengono cancellati, +in modo che @command{awk} non tenti di elaborarli come file. Se +non @`e stato specificato alcun nome di file, si usa lo standard input, e se +@`e presente pi@`u di un nome di file, lo si annota, in modo che i @value{FNS} +vengano scritti prima di ogni riga di output corrispondente: + +@example +@c file eg/prog/egrep.awk + if (criterio_di_ricerca == "") + criterio_di_ricerca = ARGV[Optind++] + + for (i = 1; i < Optind; i++) + ARGV[i] = "" + if (Optind >= ARGC) @{ + ARGV[1] = "-" + ARGC = 2 + @} else if (ARGC - Optind > 1) + servono_nomi_file++ + +# if (IGNORECASE) +# criterio_di_ricerca = tolower(criterio_di_ricerca) +@} +@c endfile +@end example + +Le ultime due righe sono solo dei commenti, in quanto non necessarie in +@command{gawk}. Per altre versioni di +@command{awk}, potrebbe essere necessario utilizzarle come istruzioni +effettive (togliendo il "#"). + +Il prossimo insieme di righe dovrebbe essere decommentato +se non si sta usando @command{gawk}. +Questa regola converte in minuscolo tutti i caratteri della riga in input, +se @`e stata specificata l'opzione @option{-i}.@footnote{Inoltre, qui si +introduce un errore subdolo; se una corrispondenza viene trovata, viene +inviata in output la riga tradotta, non quella originale.} +La regola @`e +commentata perch@'e non @`e necessaria se si usa @command{gawk}: + +@example +@c file eg/prog/egrep.awk +#@{ +# if (IGNORECASE) +# $0 = tolower($0) +#@} +@c endfile +@end example + +La funzione @code{a_inizio_file()} @`e chiamata dalla regola in @file{ftrans.awk} +quando ogni nuovo file viene elaborato. In questo caso, non c'@`e molto da fare; +ci si limita a inizializzare una variabile @code{contatore_file} a zero. +@code{contatore_file} serve a ricordare quante righe nel file corrente +corrispondono al criterio di ricerca. +Scegliere come nome di parametro @code{da_buttare} indica che sappiamo che +@code{a_inizio_file()} @`e chiamata con un parametro, ma che noi non siamo +interessati al suo valore: + +@example +@c file eg/prog/egrep.awk +function a_inizio_file(da_buttare) +@{ + contatore_file = 0 +@} +@c endfile +@end example + +La funzione @code{endfile()} viene chiamata dopo l'elaborazione di ogni file. +Ha influenza sull'output solo quando l'utente desidera un contatore del +numero di righe che sono state individuate. @code{non_stampare} @`e vero nel +caso si desideri solo il codice di +ritorno. @code{conta_e_basta} @`e vero se si desiderano solo i contatori +delle righe trovate. @command{egrep} +quindi stampa i contatori solo se +sia la stampa che il conteggio delle righe sono stati abilitati. +Il formato di output deve tenere conto del numero di file sui quali si +opera. Per finire, @code{contatore_file} @`e aggiunto a @code{totale}, in +modo da stabilire qual @`e il numero totale di righe che ha soddisfatto il +criterio di ricerca: + +@example +@c file eg/prog/egrep.awk +function endfile(file) +@{ + if (! non_stampare && conta_e_basta) @{ + if (servono_nomi_file) + print file ":" contatore_file + else + print contatore_file + @} + + totale += contatore_file +@} +@c endfile +@end example + +Si potrebbero usare i criteri di ricerca speciali @code{BEGINFILE} ed +@code{ENDFILE} +(@pxref{BEGINFILE/ENDFILE}), +ma in quel caso il programma funzionerebbe solo usando @command{gawk}. +Inoltre, questo esempio @`e stato scritto prima che a @command{gawk} venissero +aggiunti i criteri speciali @code{BEGINFILE} ed @code{ENDFILE}. + +La regola seguente fa il grosso del lavoro per trovare righe corrispondenti +al criterio di ricerca fornito. La variabile +@code{corrisponde} @`e vera se la riga @`e individuata dal criterio di ricerca. +Se l'utente chiede invece le righe che non corrispondono, il senso di +@code{corrisponde} @`e invertito, usando l'operatore @samp{!}. +@code{contatore_file} @`e incrementato con il valore di +@code{corrisponde}, che vale uno o zero, a seconda che la corrispondenza sia +stata trovata oppure no. Se la riga non corrisponde, l'istruzione +@code{next} passa ad esaminare il record successivo. + +Vengono effettuati anche altri controlli, ma soltanto se non +si sceglie di contare le righe. Prima di tutto, se l'utente desidera solo +il codice di ritorno (@code{non_stampare} @`e vero), @`e sufficiente sapere +che @emph{una} riga nel file corrisponde, e si pu@`o passare al file successivo +usando @code{nextfile}. Analogamente, se stiamo solo stampando @value{FNS}, +possiamo stampare il @value{FN}, e quindi saltare al file successivo con +@code{nextfile}. +Infine, ogni riga viene stampata, preceduta, se necessario, dal @value{FN} e +dai due punti: + +@cindex @code{!} (punto esclamativo), operatore @code{!} +@cindex punto esclamativo (@code{!}), operatore @code{!} +@example +@c file eg/prog/egrep.awk +@{ + corrisponde = ($0 ~ criterio_di_ricerca) + if (inverti_test) + corrisponde = ! corrisponde + + contatore_file += corrisponde # 1 o 0 + + if (! corrisponde) + next + + if (! conta_e_basta) @{ + if (non_stampare) + nextfile + + if (solo_nomi_file) @{ + print nome_file + nextfile + @} + + if (servono_nomi_file) + print nome_file ":" $0 + else + print + @} +@} +@c endfile +@end example + +La regola @code{END} serve a produrre il codice di ritorno corretto. Se +non ci sono corrispondenze, il codice di ritorno @`e uno; altrimenti, @`e zero: + +@example +@c file eg/prog/egrep.awk +END @{ + exit (totale == 0) +@} +@c endfile +@end example + +La funzione @code{sintassi()} stampa un messaggio per l'utente, nel caso +siano state specificate opzioni non valide, e quindi esce: + +@example +@c file eg/prog/egrep.awk +function sintassi() +@{ + print("sintassi: egrep [-csvil] [-e criterio_di_ricerca] [file ...]")\ + > "/dev/stderr" + print("\n\tegrep [-csvil] criterio_di_ricerca [file ...]") > "/dev/stderr" + exit 1 +@} +@c endfile +@end example + + +@node Programma id +@subsection Stampare informazioni sull'utente + +@cindex stampare informazioni utente +@cindex utenti, informazioni riguardo agli, stampare +@cindex @command{id}, programma di utilit@`a +@cindex programma di utilit@`a @command{id} +Il programma di utilit@`a @command{id} elenca i numeri identificativi (ID) +reali ed effettivi di un utente, e l'insieme dei gruppi a cui l'utente +appartiene, se ve ne sono. +@command{id} stampa i numeri identificativi di utente e di gruppo solo se +questi sono differenti da quelli reali. Se possibile, @command{id} elenca +anche i corrispondenti nomi di utente e di gruppo. +L'output potrebbe essere simile a questo: + +@example +$ @kbd{id} +@print{} uid=1000(arnold) gid=1000(arnold) groups=1000(arnold),4(adm),7(lp),27(sudo) +@end example + +@cindex @code{PROCINFO}, vettore, e @dfn{process ID} di utente e di gruppo +Questa informazione @`e parte di ci@`o che @`e reso disponibile dal vettore +@code{PROCINFO} di @command{gawk} (@pxref{Variabili predefinite}). +Comunque, il programma di utilit@`a @command{id} fornisce un output pi@`u +comprensibile che non una semplice lista di numeri. + +Ecco una versione semplice di @command{id} scritta in @command{awk}. +Usa le funzioni di libreria che riguardano il database degli utenti +(@pxref{Funzioni Passwd}) +e le funzioni di libreria che riguardano il database dei gruppi +(@pxref{Funzioni Group}) +contenute +@iftex +nel +@end iftex +@ifnottex +in +@end ifnottex +@ref{Funzioni di libreria}. + +Il programma @`e abbastanza semplice. Tutto il lavoro @`e svolto nella regola +@code{BEGIN}. I numeri ID di utente e di gruppo sono ottenuti da +@code{PROCINFO}. +Il codice @`e ripetitivo. La riga nel database degli utenti che descrive +l'ID reale dell'utente @`e divisa in parti, separate tra loro da @samp{:}. +Il nome @`e il primo campo. Un codice analogo @`e usato per l'ID effettivo, e +per i numeri che descrivono i gruppi: + +@cindex @code{id.awk}, programma +@cindex programma @code{id.awk} +@example +@c file eg/prog/id.awk +# id.awk --- implement id in awk +# +# Richiede funzioni di libreria per utente e gruppo +@c endfile +@ignore +@c file eg/prog/id.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# May 1993 +# Revised February 1996 +# Revised May 2014 +# Revised September 2014 + +@c endfile +@end ignore +@c file eg/prog/id.awk +# l'output @`e: +# uid=12(pippo) euid=34(pluto) gid=3(paperino) \ +# egid=5(paperina) groups=9(nove),2(due),1(uno) + +@group +BEGIN @{ + uid = PROCINFO["uid"] + euid = PROCINFO["euid"] + gid = PROCINFO["gid"] + egid = PROCINFO["egid"] +@end group + + printf("uid=%d", uid) + pw = getpwuid(uid) + stampa_primo_campo(pw) + + if (euid != uid) @{ + printf(" euid=%d", euid) + pw = getpwuid(euid) + stampa_primo_campo(pw) + @} + + printf(" gid=%d", gid) + pw = getgrgid(gid) + stampa_primo_campo(pw) + + if (egid != gid) @{ + printf(" egid=%d", egid) + pw = getgrgid(egid) + stampa_primo_campo(pw) + @} + + for (i = 1; ("group" i) in PROCINFO; i++) @{ + if (i == 1) + printf(" gruppi=") + group = PROCINFO["group" i] + printf("%d", group) + pw = getgrgid(group) + stampa_primo_campo(pw) + if (("group" (i+1)) in PROCINFO) + printf(",") + @} + + print "" +@} + +function stampa_primo_campo(str, a) +@{ + if (str != "") @{ + split(str, a, ":") + printf("(%s)", a[1]) + @} +@} +@c endfile +@end example + +Il test incluso nel ciclo @code{for} @`e degno di nota. +Ogni ulteriore gruppo nel vettore @code{PROCINFO} ha come indice da +@code{"group1"} a @code{"group@var{N}"} dove il numero +@var{N} @`e il numero totale di gruppi ulteriori). +Tuttavia, non si sa quanti di questi gruppi ci siano per un dato utente. + +Questo ciclo inizia da uno, concatena il valore di ogni iterazione con +@code{"group"}, e poi usando l'istruzione @code{in} verifica se quella +chiave @`e nel vettore (@pxref{Visitare elementi}). Quando @code{i} @`e +incrementato oltre l'ultimo gruppo presente nel vettore, il ciclo termina. + +Il ciclo funziona correttamente anche se @emph{non} ci sono ulteriori +gruppi; in quel caso la condizione risulta falsa fin dal primo controllo, e +il corpo del ciclo non viene mai eseguito. + +La funzione @code{stampa_primo_campo()} semplicemente incapsula quelle parti di +codice che vengono usate ripetutamente, rendendo il programma pi@`u conciso e +ordinato. +In particolare, inserendo in questa funzione il test per la stringa nulla +consente di risparmiare parecchie righe di programma. + + +@node Programma split +@subsection Suddividere in pezzi un file grosso + +@c FIXME: One day, update to current POSIX version of split + +@cindex file, splitting +@cindex @code{split}, programma di utilit@`a +@cindex programma di utilit@`a @code{split} +Il programma @command{split} divide grossi file di testo in pezzi pi@`u piccoli. +La sua sintassi @`e la seguente:@footnote{Questo @`e la sintassi tradizionale. +La versione POSIX del comando ha una sintassi differente, ma per lo scopo di +questo programma @command{awk} la cosa non ha importanza.} + +@display +@command{split} [@code{-@var{contatore}}] [@var{file}] [@var{prefisso}] +@end display + +Per default, +i file di output avranno nome @file{xaa}, @file{xab}, e cos@`{@dotless{i}} via. Ogni file +contiene 1.000 righe, con la probabile +eccezione dell'ultimo file. Per +cambiare il numero di righe in ogni file, va indicato un numero sulla riga +di comando, preceduto da un segno meno (p.es., @samp{-500} per file con 500 +righe ognuno invece che 1.000). Per modificare i nomi dei file di output in +qualcosa del tipo +@file{miofileaa}, @file{miofileab}, e cos@`{@dotless{i}} via, va indicato un argomento +ulteriore che specifica il prefisso del @value{FN}. + +Ecco una versione di @command{split} in @command{awk}. Usa le funzioni +@code{ord()} e @code{chr()} descritte nella +@ref{Funzioni ordinali}. + +Il programma dapprima imposta i suoi valori di default, e poi controlla che +non siano stati specificati troppi argomenti. Quindi esamina gli argomenti +uno alla volta. Il primo +argomento potrebbe essere un segno meno seguito da un numero. Poich@'e il +numero in questione pu@`o apparire negativo, lo si fa diventare positivo, e +viene usato per contare le righe. Il nome del @value{DF} @`e per ora ignorato +e l'ultimo argomento @`e usato come prefisso per i @value{FNS} in output: + +@cindex @code{split.awk}, programma di utilit@`a +@cindex programma di utilit@`a @code{split.awk} +@example +@c file eg/prog/split.awk +# split.awk --- comando split scritto in awk +# +# Richiede le funzioni di libreria ord() e chr() +@c endfile +@ignore +@c file eg/prog/split.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# May 1993 +# Revised slightly, May 2014 + +@c endfile +@end ignore +@c file eg/prog/split.awk +# sintassi: split [-contatore] [file] [nome_in_output] + +BEGIN @{ + outfile = "x" # default + contatore = 1000 + if (ARGC > 4) + sintassi() + + i = 1 + if (i in ARGV && ARGV[i] ~ /^-[[:digit:]]+$/) @{ + contatore = -ARGV[i] + ARGV[i] = "" + i++ + @} + # testa argv nel caso che si legga da stdin invece che da file + if (i in ARGV) + i++ # salta nome file-dati + if (i in ARGV) @{ + outfile = ARGV[i] + ARGV[i] = "" + @} + + s1 = s2 = "a" + out = (outfile s1 s2) +@} +@c endfile +@end example + +La regola seguente fa il grosso del lavoro. @code{contatore_t} +(contatore temporaneo) tiene conto di +quante righe sono state stampate sul file di output finora. Se questo +numero supera il valore di @code{contatore}, @`e ora di chiudere il file +corrente e di iniziare a scriverne uno nuovo. +Le variabili @code{s1} e @code{s2} sono usate per creare i suffissi +da apporre a @value{FN}. Se entrambi arrivano al valore @samp{z}, il file +@`e troppo grosso. Altrimenti, @code{s1} passa alla successiva lettera +dell'alfabeto e @code{s2} ricomincia da @samp{a}: + +@c else on separate line here for page breaking +@example +@c file eg/prog/split.awk +@{ + if (++contatore_t > contatore) @{ + close(out) + if (s2 == "z") @{ + if (s1 == "z") @{ + printf("split: %s @`e troppo grosso da suddividere\n", + nome_file) > "/dev/stderr" + exit 1 + @} + s1 = chr(ord(s1) + 1) + s2 = "a" + @} +@group + else + s2 = chr(ord(s2) + 1) +@end group + out = (outfile s1 s2) + contatore_t = 1 + @} + print > out +@} +@c endfile +@end example + +@noindent +La funzione @code{sintassi()} stampa solo un messaggio di errore ed esce: + +@example +@c file eg/prog/split.awk +function sintassi() +@{ + print("sintassi: split [-num] [file] [nome_in_output]") > "/dev/stderr" + exit 1 +@} +@c endfile +@end example + +Questo programma @`e un po' approssimativo; conta sul fatto che @command{awk} chiuda +automaticamente l'ultimo file invece di farlo in una regola @code{END}. +Un altro presupposto del programma @`e che le lettere dell'alfabeto siano +in posizioni consecutive nella codifica in uso, il che non @`e vero per i +sistemi che usano la codifica EBCDIC. + +@ifset FOR_PRINT +Si potrebbe pensare a come eliminare l'uso di +@code{ord()} e @code{chr()}; la cosa si pu@`o fare in modo tale da risolvere +anche il problema posto dalla codifica EBCDIC. +@end ifset + + +@node Programma tee +@subsection Inviare l'output su pi@`u di un file + +@cindex file, multipli@comma{} duplicare l'output su +@cindex output, duplicarlo su pi@`u file +@cindex @code{tee}, programma di utilit@`a +@cindex programma di utilit@`a @code{tee} +Il programma @code{tee} @`e noto come @dfn{pipe fitting} (tubo secondario). +@code{tee} copia il suo standard input al suo standard output e inoltre lo +duplica scrivendo sui file indicati nella riga di comando. La sua sintassi +@`e la seguente: + +@display +@command{tee} [@option{-a}] @var{file} @dots{} +@end display + +L'opzione @option{-a} chiede a @code{tee} di aggiungere in fondo al file +indicato, invece che riscriverlo dall'inizio. + +La regola @code{BEGIN} dapprima fa una copia di tutti gli argomenti presenti +sulla riga di comando, in un vettore di nome @code{copia}. +@code{ARGV[0]} non serve, e quindi non viene copiato. +@code{tee} non pu@`o usare @code{ARGV} direttamente, perch@'e @command{awk} tenta +di elaborare ogni @value{FN} in @code{ARGV} come dati in input. + +@cindex flag, variabili di tipo +@cindex variabili di tipo indicatore [@dfn{flag}] +Se il primo argomento @`e @option{-a}, la variabile flag +@code{append} viene impostata a vero, e sia @code{ARGV[1]} che +@code{copia[1]} vengono cancellati. Se @code{ARGC} @`e minore di due, nessun +@value{FN} @`e stato fornito, e @code{tee} stampa un messaggio di sintassi ed +esce. +Infine, @command{awk} viene obbligato a leggere lo standard input +impostando @code{ARGV[1]} al valore @code{"-"} e @code{ARGC} a due: + +@cindex @code{tee.awk}, programma di utilit@`a +@cindex programma di utilit@`a @code{tee.awk} +@example +@c file eg/prog/tee.awk +# tee.awk --- tee in awk +# +# Copia lo standard input a tutti i file di output indicati. +# Aggiunge in fondo se viene data l'opzione -a. +# +@c endfile +@ignore +@c file eg/prog/tee.awk +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# May 1993 +# Revised December 1995 + +@c endfile +@end ignore +@c file eg/prog/tee.awk +BEGIN @{ + for (i = 1; i < ARGC; i++) + copia[i] = ARGV[i] + + if (ARGV[1] == "-a") @{ + append = 1 + delete ARGV[1] + delete copia[1] + ARGC-- + @} + if (ARGC < 2) @{ + print "sintassi: tee [-a] file ..." > "/dev/stderr" + exit 1 + @} + ARGV[1] = "-" + ARGC = 2 +@} +@c endfile +@end example + +La seguente regola @`e sufficiente da sola a eseguire il lavoro. Poich@'e non @`e +presente alcun criterio di ricerca, la regola @`e eseguita per ogni riga di +input. Il corpo della regola si limita a stampare la riga su ogni file +indicato nella riga di comando, e poi sullo standard output: + +@example +@c file eg/prog/tee.awk +@{ + # spostare l'if fuori dal ciclo ne velocizza l'esecuzione + if (append) + for (i in copia) + print >> copia[i] + else + for (i in copia) + print > copia[i] + print +@} +@c endfile +@end example + +@noindent +@`E anche possibile scrivere il ciclo cos@`{@dotless{i}}: + +@example +for (i in copia) + if (append) + print >> copia[i] + else + print > copia[i] +@end example + +@noindent +Questa forma @`e pi@`u concisa, ma anche meno efficiente. L'@samp{if} @`e +eseguito per ogni record e per ogni file di output. Duplicando il corpo +del ciclo, l'@samp{if} @`e eseguito solo una volta per ogni record in input. +Se ci sono +@var{N} record in input e @var{M} file di output, il primo metodo esegue solo +@var{N} istruzioni @samp{if}, mentre il secondo esegue +@var{N}@code{*}@var{M} istruzioni @samp{if}. + +Infine, la regola @code{END} fa pulizia, chiudendo tutti i file di output: + +@example +@c file eg/prog/tee.awk +END @{ + for (i in copia) + close(copia[i]) +@} +@c endfile +@end example + +@node Programma uniq +@subsection Stampare righe di testo non duplicate + +@c FIXME: One day, update to current POSIX version of uniq + +@cindex stampare righe di testo non duplicate +@cindex testo@comma{} stampare, righe non duplicate di +@cindex @command{uniq}, programma di utilit@`a +@cindex programma di utilit@`a @command{uniq} +Il programma di utilit@`a @command{uniq} legge righe di dati ordinati sul suo +standard input, e per default rimuove righe duplicate. In altre parole, +stampa solo righe uniche; da cui il +nome. @command{uniq} ha diverse opzioni. La sintassi @`e la seguente: + +@display +@command{uniq} [@option{-udc} [@code{-@var{n}}]] [@code{+@var{n}}] [@var{file_input} [@var{file_output}]] +@end display + +Le opzioni per @command{uniq} sono: + +@table @code +@item -d +Stampa solo righe ripetute (duplicate). + +@item -u +Stampa solo righe non ripetute (uniche). + +@item -c +Contatore righe. Quest'opzione annulla le opzioni @option{-d} e @option{-u}. +Sia le righe ripetute che quelle non ripetute vengono contate. + +@item -@var{n} +Salta @var{n} campi prima di confrontare le righe. La definizione di campo +@`e simile al default di @command{awk}: caratteri non bianchi, separati da +sequenze di spazi e/o TAB. + +@item +@var{n} +Salta @var{n} caratteri prima di confrontare le righe. Eventuali campi +specificati con @samp{-@var{n}} sono saltati prima. + +@item @var{file_input} +I dati sono letti dal file in input specificato sulla riga di comando, invece +che dallo standard input. + +@item @var{file_output} +L'output generato @`e scritto sul file di output specificato, invece che sullo +standard output. +@end table + +Normalmente @command{uniq} si comporta come se siano state specificate entrambe +le opzioni @option{-d} e @option{-u}. + +@command{uniq} usa la +funzione di libreria @code{getopt()} +(@pxref{Funzione getopt}) +e la funzione di libreria @code{join()} +(@pxref{Funzione join}). + +Il programma inizia con una funzione @code{sintassi()} e poi con una breve +spiegazione delle opzioni e del loro significato, sotto forma di commenti. +La regola @code{BEGIN} elabora gli argomenti della riga di comando e le +opzioni. Viene usato un artificio per poter impiegare @code{getopt()} con +opzioni della forma @samp{-25}, +trattando quest'opzione come la lettera di opzione @samp{2} con +l'argomento @samp{5}. Se si specificano due o pi@`u cifre (@code{Optarg} +sembra essere numerico), @code{Optarg} @`e concatenato con la cifra che +costituisce l'opzione e poi al risultato @`e addizionato zero, per trasformarlo +in un numero. Se c'@`e solo una cifra nell'opzione, @code{Optarg} non @`e +necessario. In tal caso, @code{Optind} dev'essere decrementata, in modo che +@code{getopt()} la elabori quando viene nuovamente richiamato. Questo codice +@`e sicuramente un po' intricato. + +Se non sono specificate opzioni, per default si stampano sia le righe +ripetute che quelle non ripetute. Il file di output, se specificato, @`e +assegnato a @code{file_output}. In precedenza, @code{file_output} @`e +inizializzato allo standard output, @file{/dev/stdout}: + +@cindex @code{uniq.awk}, programma di utilit@`a +@cindex programma di utilit@`a @code{uniq.awk} +@example +@c file eg/prog/uniq.awk +@group +# uniq.awk --- implementa uniq in awk +# +# Richiede le funzioni di libreria getopt() e join() +@end group +@c endfile +@ignore +@c file eg/prog/uniq.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# May 1993 +@c endfile +@end ignore +@c file eg/prog/uniq.awk + +function sintassi() +@{ + print("sintassi: uniq [-udc [-n]] [+n] [ in [ out ]]") > "/dev/stderr" + exit 1 +@} + +# -c contatore di righe. prevale su -d e -u +# -d solo righe ripetute +# -u solo righe non ripetute +# -n salta n campi +# +n salta n caratteri, salta prima eventuali campi + +BEGIN @{ + contatore = 1 + file_output = "/dev/stdout" + opts = "udc0:1:2:3:4:5:6:7:8:9:" + while ((c = getopt(ARGC, ARGV, opts)) != -1) @{ + if (c == "u") + solo_non_ripetute++ + else if (c == "d") + solo_ripetute++ + else if (c == "c") + conta_record++ + else if (index("0123456789", c) != 0) @{ + # getopt() richiede argomenti per le opzioni + # questo consente di gestire cose come -5 + if (Optarg ~ /^[[:digit:]]+$/) + contatore_file = (c Optarg) + 0 + else @{ + contatore_file = c + 0 + Optind-- + @} + @} else + sintassi() + @} + + if (ARGV[Optind] ~ /^\+[[:digit:]]+$/) @{ + conta_caratteri = substr(ARGV[Optind], 2) + 0 + Optind++ + @} + + for (i = 1; i < Optind; i++) + ARGV[i] = "" + + if (solo_ripetute == 0 && solo_non_ripetute == 0) + solo_ripetute = solo_non_ripetute = 1 + + if (ARGC - Optind == 2) @{ + file_output = ARGV[ARGC - 1] + ARGV[ARGC - 1] = "" + @} +@} +@c endfile +@end example + +La funzione seguente, @code{se_sono_uguali()}, confronta la riga corrente, +@code{$0}, con la riga precedente, @code{ultima}. Gestisce il salto di +campi e caratteri. Se non sono stati richiesti n@'e contatori di campo n@'e +contatori di carattere, @code{se_sono_uguali()} restituisce uno o zero a +seconda del risultato di un semplice confronto tra le stringhe @code{ultima} +e @code{$0}. + +In caso contrario, le cose si complicano. Se devono essere saltati dei campi, +ogni riga viene suddivisa in un vettore, usando @code{split()} +(@pxref{Funzioni per stringhe}); i campi desiderati sono poi nuovamente uniti in +un'unica riga usando @code{join()}. Le righe ricongiunte vengono +immagazzinate in @code{campi_ultima} e @code{campi_corrente}. Se non ci +sono campi da saltare, @code{campi_ultima} e @code{campi_corrente} sono +impostati a @code{ultima} e @code{$0}, rispettivamente. Infine, se +occorre saltare dei caratteri, si usa @code{substr()} per eliminare i primi +@code{conta_caratteri} caratteri in @code{campi_ultima} e +@code{campi_corrente}. Le due stringhe sono poi confrontare e +@code{se_sono_uguali()} restituisce il risultato del confronto: + +@example +@c file eg/prog/uniq.awk +function se_sono_uguali( n, m, campi_ultima, campi_corrente,\ +vettore_ultima, vettore_corrente) +@{ + if (contatore_file == 0 && conta_caratteri == 0) + return (ultima == $0) + + if (contatore_file > 0) @{ + n = split(ultima, vettore_ultima) + m = split($0, vettore_corrente) + campi_ultima = join(vettore_ultima, contatore_file+1, n) + campi_corrente = join(vettore_corrente, contatore_file+1, m) + @} else @{ + campi_ultima = ultima + campi_corrente = $0 + @} + if (conta_caratteri) @{ + campi_ultima = substr(campi_ultima, conta_caratteri + 1) + campi_corrente = substr(campi_corrente, conta_caratteri + 1) + @} + + return (campi_ultima == campi_corrente) +@} +@c endfile +@end example + +Le due regole seguenti sono il corpo del programma. La prima @`e eseguita solo +per la prima riga dei dati. Imposta @code{ultima} al record corrente +@code{$0}, in modo che le righe di testo successive abbiano qualcosa con cui +essere confrontate. + +La seconda regola fa il lavoro. La variabile @code{uguale} vale uno o zero, +a seconda del risultato del confronto effettuato in @code{se_sono_uguali()}. +Se @command{uniq} sta contando le righe ripetute, e le righe sono uguali, +viene incrementata la variabile @code{contatore}. +Altrimenti, viene stampata la riga e azzerato @code{contatore}, +perch@'e le due righe non sono uguali. + +Se @command{uniq} non sta contando, e se le righe sono uguali, +@code{contatore} @`e incrementato. +Non viene stampato niente, perch@'e l'obiettivo @`e quello di rimuovere i duplicati. +Altrimenti, se @command{uniq} sta contando le righe ripetute e viene trovata pi@`u +di una riga, o se @command{uniq} sta contando le righe non ripetute +e viene trovata solo una riga, questa riga viene stampata, e @code{contatore} @`e +azzerato. + +Infine, una logica simile @`e usata nella regola @code{END} per stampare +l'ultima riga di dati in input: + +@example +@c file eg/prog/uniq.awk +NR == 1 @{ + ultima = $0 + next +@} + +@{ + uguale = se_sono_uguali() + + if (conta_record) @{ # prevale su -d e -u + if (uguale) + contatore++ + else @{ + printf("%4d %s\n", contatore, ultima) > file_output + ultima = $0 + contatore = 1 # reset + @} + next + @} + + if (uguale) + contatore++ + else @{ + if ((solo_ripetute && contatore > 1) || + (solo_non_ripetute && contatore == 1)) + print ultima > file_output + ultima = $0 + contatore = 1 + @} +@} + +END @{ + if (conta_record) + printf("%4d %s\n", contatore, ultima) > file_output + else if ((solo_ripetute && contatore > 1) || + (solo_non_ripetute && contatore == 1)) + print ultima > file_output + close(file_output) +@} +@c endfile +@end example + +@c FIXME: Include this? +@ignore +This program does not follow our recommended convention of naming +global variables with a leading capital letter. Doing that would +make the program a little easier to follow. +@end ignore + +@ifset FOR_PRINT +La logica per scegliere quali righe stampare rappresenta una @dfn{macchina a +stati}, che @`e ``un dispositivo che pu@`o trovarsi in una tra un dato numero di +condizioni stabili, a seconda della sua condizione precedente e del valore +corrente dei suoi input.''@footnote{Questa @`e la definizione trovata +cercando @code{define: state machine} in Google.} +Brian Kernighan suggerisce che +``un approccio alternativo alle macchine a stati @`e quello di mettere l'input +in un vettore, e poi usare gli indici. @`E quasi sempre pi@`u facile da +programmare e, per molti input in cui si pu@`o usare questo metodo, +altrettanto veloce.'' Si consideri come riscrivere la logica di questo +programma per seguite questo suggerimento. +@end ifset + + + +@node Programma wc +@subsection Contare cose + +@c FIXME: One day, update to current POSIX version of wc + +@cindex contare +@cindex file in input, contare elementi nel +@cindex parole, contare le +@cindex caratteri, contare i +@cindex righe, contare le +@cindex @command{wc}, programma di utilit@`a +@cindex programma di utilit@`a @command{wc} +Il programma di utilit@`a @command{wc} (@dfn{word count}, contatore di parole) +conta righe, parole, e caratteri in uno o pi@`u file in input. La sua sintassi +@`e la seguente: + +@display +@command{wc} [@option{-lwc}] [@var{file} @dots{}] +@end display + +Se nessun file @`e specificato sulla riga di comando, @command{wc} legge il suo +standard input. Se ci sono pi@`u file, stampa anche il contatore totale di +tutti i file. Le opzioni e il loro significato sono i seguenti: + +@table @code +@item -l +Conta solo le righe. + +@item -w +Conta solo le parole. +Una ``parola'' @`e una sequenza contigua di caratteri non bianchi, separata da +spazi e/o TAB. Fortunatamente, questo @`e il modo normale in cui @command{awk} +separa i campi nei suoi record in input. + +@item -c +Conta solo i caratteri. +@end table + +Implementare @command{wc} in @command{awk} @`e particolarmente elegante, +perch@'e @command{awk} fa molto lavoro al posto nostro; divide le righe in +parole (cio@`e, campi) e le conta, conta le righe (cio@`e, i record), +e pu@`o facilmente dire quanto @`e lunga una riga. + +Questo programma usa la funzione di libreria @code{getopt()} +(@pxref{Funzione getopt}) +e le funzioni di passaggio da un file all'altro +(@pxref{Funzione filetrans}). + +Questa versione ha una differenza significativa rispetto alle versioni +tradizionali di @command{wc}: stampa sempre i contatori rispettando l'ordine +righe, parole e caratteri. Le versioni tradizionali rilevano l'ordine in cui +sono specificate le opzioni @option{-l}, @option{-w} e @option{-c} sulla riga +di comando, e stampano i contatori in quell'ordine. + +La regola @code{BEGIN} si occupa degli argomenti. La variabile +@code{stampa_totale} @`e vera se pi@`u di un file @`e presente sulla +riga di comando: + +@cindex @code{wc.awk}, programma di utilit@`a +@cindex programma di utilit@`a @code{wc.awk} +@example +@c file eg/prog/wc.awk +# wc.awk --- conta righe, parole, caratteri +@c endfile +@ignore +@c file eg/prog/wc.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# May 1993 +@c endfile +@end ignore +@c file eg/prog/wc.awk + +# Opzioni: +# -l conta solo righe +# -w conta solo parole +# -c conta solo caratteri +# +# Il default @`e di contare righe, parole, caratteri +# +# Richiede le funzioni di libreria getopt() +# e il programma di libreria che gestisce +# il passaggio da un file dati al successivo + +BEGIN @{ + # consente a getopt() di stampare un messaggio se si specificano + # opzioni non valide. Noi le ignoriamo + while ((c = getopt(ARGC, ARGV, "lwc")) != -1) @{ + if (c == "l") + conta_righe = 1 + else if (c == "w") + conta_parole = 1 + else if (c == "c") + conta_caratteri = 1 + @} + for (i = 1; i < Optind; i++) + ARGV[i] = "" + + # se nessuna opzione @`e specificata, conta tutto + if (! conta_righe && ! conta_parole && ! conta_caratteri) + conta_righe = conta_parole = conta_caratteri = 1 + + stampa_totale = (ARGC - i > 1) +@} +@c endfile +@end example + +La funzione @code{a_inizio_file()} @`e semplice; si limita ad azzerare i contatori +di righe, parole e caratteri, e salva il valore corrente di @value{FN} in +@code{nome_file}: + +@example +@c file eg/prog/wc.awk +function a_inizio_file(file) +@{ + righe = parole = caratteri = 0 + nome_file = FILENAME +@} +@c endfile +@end example + +La funzione @code{a_fine_file()} aggiunge i numeri del file corrente al totale +di righe, parole, e caratteri. Poi stampa i numeri relativi al file appena +letto. La funzione +@code{a_inizio_file()} azzera i numeri relativi al @value{DF} seguente: + +@example +@c file eg/prog/wc.awk +function a_fine_file(file) +@{ + totale_righe += righe + totale_parole += parole + totale_caratteri += caratteri + if (conta_righe) + printf "\t%d", righe +@group + if (conta_parole) + printf "\t%d", parole +@end group + if (conta_caratteri) + printf "\t%d", caratteri + printf "\t%s\n", nome_file +@} +@c endfile +@end example + +C'@`e una regola che viene eseguita per ogni riga. Aggiunge la lunghezza del record +pi@`u uno, a @code{caratteri}.@footnote{Poich@'e @command{gawk} gestisce le +localizzazioni in cui un carattere pu@`o occupare pi@`u di un byte, questo codice +conta i caratteri, non i byte.} +Aggiungere uno alla lunghezza del record +@`e necessario, perch@'e il carattere di ritorno a capo, che separa i record +(il valore di @code{RS}) non @`e parte del record stesso, e quindi non @`e +incluso nella sua lunghezza. Poi, @code{righe} @`e incrementata per ogni riga +letta, e @code{parole} @`e incrementato con il valore @code{NF}, che @`e il +numero di ``parole'' su questa riga: + +@example +@c file eg/prog/wc.awk +# per ogni riga... +@{ + caratteri += length($0) + 1 # aggiunge un ritorno a capo + righe++ + parole += NF +@} +@c endfile +@end example + +Infine, la regola @code{END} si limita a stampare i totali per tutti i file: + +@example +@c file eg/prog/wc.awk +END @{ + if (stampa_totale) @{ + if (conta_righe) + printf "\t%d", totale_righe + if (conta_parole) + printf "\t%d", totale_parole + if (conta_caratteri) + printf "\t%d", totale_caratteri + print "\ttotale" + @} +@} +@c endfile +@end example + +@node Programmi vari +@section Un paniere di programmi @command{awk} + +Questa @value{SECTION} @`e un ``paniere'' che contiene vari programmi. +Si spera che siano interessanti e divertenti. + +@menu +* Programma dupword:: Trovare parole duplicate in un documento. +* Programma alarm:: Un programma di sveglia. +* Programma translate:: Un programma simile al programma di utilit@`a + @command{tr}. +* Programma labels:: Stampare etichette per lettere. +* Programma utilizzo parole:: Un programma per produrre un contatore + dell'uso di parole in un testo. +* Programma riordino diario:: Eliminare righe doppie da un file di + cronologia. +* Programma extract :: Estrarre programmi da file sorgenti Texinfo. +* Programma sed semplice:: Un semplice editor di flusso. +* Programma igawk:: Un programma per fornire ad + @command{awk} la possibilit@`a di includere + file. +* Programma anagram:: Trovare anagrammi da una lista di parole. +* Programma signature:: La gente fa cose stupefacenti se ha troppo + tempo libero. +@end menu + +@node Programma dupword +@subsection Trovare parole duplicate in un documento + +@cindex parole duplicate, ricerca di +@cindex ricerca di parole +@cindex documenti@comma{} ricerca in +Un errore comune quando si scrive un testo lungo @`e quello di ripetere +accidentalmente delle parole. Tipicamente lo si pu@`o vedere in testi del tipo +``questo questo programma fa quanto segue@dots{}'' Quando il testo @`e pubblicato in rete, spesso +le parole duplicate sono poste tra il termine di +@iftex +di +@end iftex +una riga e l'inizio di un'altra, il che rende difficile scoprirle. +@c as here! + +Questo programma, @file{dupword.awk}, legge un file una riga alla volta +e cerca le occorrenze adiacenti della stessa parola. Conserva anche +l'ultima parola di ogni riga (nella variabile @code{precedente}) per +confrontarla con la prima parola sulla riga successiva. + +@cindex Texinfo +Le prime due istruzioni fanno s@`{@dotless{i}} che la riga sia tutta in minuscolo, +in modo che, per esempio, ``Il'' e ``il'' risultino essere la stessa parola. +L'istruzione successiva sostituisce i caratteri che sono non alfanumerici e +diversi dagli +spazi bianchi con degli spazi, in modo che neppure la punteggiatura influenzi +i confronti. +I caratteri sono rimpiazzati da spazi in modo che i controlli di formattazione +non creino parole prive di senso (p.es., l'espressione Texinfo +@samp{@@code@{NF@}} diventa @samp{codeNF}, se ci si limita a eliminare la +punteggiatura). Il record @`e poi +suddiviso di nuovo in campi, producendo cos@`{@dotless{i}} solo la lista delle parole +presenti sulla riga, esclusi eventuali campi nulli. + +Se, dopo aver rimosso tutta la punteggiatura, non rimane alcun campo, il +record corrente @`e saltato. In caso contrario, il programma esegue il ciclo +per ogni parola, confrontandola con quella che la precede: + +@cindex @code{dupword.awk}, programma +@cindex programma @code{dupword.awk} +@example +@c file eg/prog/dupword.awk +# dupword.awk --- trova parole duplicate in un testo +@c endfile +@ignore +@c file eg/prog/dupword.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# December 1991 +# Revised October 2000 + +@c endfile +@end ignore +@c file eg/prog/dupword.awk +@{ + $0 = tolower($0) + gsub(/[^[:alnum:][:blank:]]/, " "); + $0 = $0 # divide di nuovo in campi + if (NF == 0) + next + if ($1 == prec) + printf("%s:%d: duplicato %s\n", + nome_file, FNR, $1) + for (i = 2; i <= NF; i++) + if ($i == $(i-1)) + printf("%s:%d: duplicato %s\n", + nome_file, FNR, $i) + prec = $NF +@} +@c endfile +@end example + +@node Programma alarm +@subsection Un programma di sveglia +@cindex insonnia, cura per +@cindex Robbins, Arnold +@quotation +@i{Nessuna cura contro l'insonnia @`e efficace quanto una sveglia che suona.} +@author Arnold Robbins +@end quotation +@cindex Quanstrom, Erik +@ignore +Date: Sat, 15 Feb 2014 16:47:09 -0500 +Subject: Re: 9atom install question +Message-ID: <l2jcvx6j6mey60xnrkb0hhob.1392500829294@email.android.com> +From: Erik Quanstrom <quanstro@quanstro.net> +To: Aharon Robbins <arnold@skeeve.com> + +yes. + +- erik + +Aharon Robbins <arnold@skeeve.com> wrote: + +>> sleep is for web developers. +> +>Can I quote you, in the gawk manual? +> +>Thanks, +> +>Arnold +@end ignore +@quotation +@i{Il sonno @`e per sviluppatori web.} +@author Erik Quanstrom +@end quotation + +@cindex tempo, sveglia, programma di esempio +@cindex sveglia, programma di esempio +Il seguente programma @`e un semplice programma di ``sveglia''. +Si pu@`o specificare un'ora del giorno e un messaggio opzionale. All'ora +specificata, il programma stampa il messaggio sullo standard output. Inoltre, +si pu@`o 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 @code{getlocaltime()} +@iftex +dalla +@end iftex +@ifnottex +da +@end ifnottex +@ref{Funzione getlocaltime}. + +Tutto il lavoro @`e svolto nella regola @code{BEGIN}. La prima parte @`e +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'', @code{"\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@'e nel caso che l'utente non stia guardando il computer.) +Per amor di variet@`a, questo programma usa un'istruzione @code{switch} +(@pxref{Istruzione switch}), ma l'elaborazione potrebbe anche essere fatta +con una serie di istruzioni @code{if}-@code{else}. +Ecco il programma: + +@cindex @code{alarm.awk}, programma +@cindex programma @code{alarm.awk} +@example +@c file eg/prog/alarm.awk +# alarm.awk --- impostare una sveglia +# +# Richiede la funzione di libreria getlocaltime() +@c endfile +@ignore +@c file eg/prog/alarm.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# May 1993 +# Revised December 2010 + +@c endfile +@end ignore +@c file eg/prog/alarm.awk +# sintassi: alarm a_che_ora [ "messaggio" [ contatore [ ritardo ] ] ] + +BEGIN @{ + # Controllo iniziale congruit@`a 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 +@group + if (contatore == 0) + contatore = 5 +@end group + if (messaggio == "") + messaggio = sprintf("\aAdesso sono le %s!\a", ARGV[1]) + else if (index(message, "\a") == 0) + messaggio = "\a" messaggio "\a" +@c endfile +@end example + +La successiva @value{SECTION} di codice scompone l'ora specificata in ore e +minuti, la converte (se @`e 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 @`e il tempo di attesa che deve passare +prima di far scattare la sveglia: + +@example +@c file eg/prog/alarm.awk + # 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 @`e in formato 12-ore ed @`e 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 @`e nel passato!" > "/dev/stderr" + exit 1 + @} +@c endfile +@end example + +@cindex @command{sleep}, programma di utilit@`a +@cindex programma di utilit@`a @command{sleep} +Infine, il programma usa la funzione @code{system()} +(@pxref{Funzioni di I/O}) +per chiamare il programma di utilit@`a @command{sleep}. Il programma di utilit@`a +@command{sleep} non fa altro che aspettare per il numero di secondi +specificato. Se il codice di ritorno restituito @`e diverso da zero, il +programma suppone che @command{sleep} sia stato interrotto ed esce. Se +@command{sleep} @`e terminato con un codice di ritorno corretto, (zero), il +programma stampa il messaggio in un ciclo, utilizzando ancora @command{sleep} +per ritardare per il numero di secondi necessario: + +@example +@c file eg/prog/alarm.awk + # zzzzzz..... esci se sleep @`e interrotto + if (system(sprintf("sleep %d", sonno)) != 0) + exit 1 + + # @`e ora di avvisare! + command = sprintf("sleep %d", ritardo) + for (i = 1; i <= contatore; i++) @{ + print messaggio + # se il comando sleep @`e interrotto, esci + if (system(command) != 0) + break + @} + + exit 0 +@} +@c endfile +@end example + +@node Programma translate +@subsection Rimpiazzare o eliminare caratteri + +@cindex caratteri, rimpiazzare +@cindex rimpiazzare caratteri +@cindex @command{tr}, programma di utilit@`a +@cindex programma di utilit@`a @command{tr} +Il programma di utilit@`a di sistema @command{tr} rimpiazza caratteri. Per +esempio, @`e spesso usato per trasformare lettere maiuscole in lettere minuscole +in vista di ulteriori elaborazioni: + +@example +@var{generare dei dati} | tr 'A-Z' 'a-z' | @var{elaborare dei dati} @dots{} +@end example + +@command{tr} richiede due liste di caratteri.@footnote{Su alcuni sistemi +pi@`u datati, incluso Solaris, la versione di sistema di @command{tr} pu@`o +richiedere che le liste siano scritte come espressioni di intervallo, +racchiuse in parentesi quadre +(@samp{[a-z]}) e tra apici, per evitare che la shell effettui +espansioni di @value{FN}. Questo non @`e un miglioramento.} Quando +si elabora l'input, il primo carattere della prima lista @`e rimpiazzato con il +primo carattere della seconda lista, il secondo carattere della prima lista @`e +rimpiazzato con il secondo carattere della seconda lista, e cos@`{@dotless{i}} via. Se ci +sono pi@`u caratteri nella lista ``da'' che in quella ``a'', l'ultimo carattere +della lista ``a'' @`e usato per i restanti caratteri della lista ``da''. + +In un lontano passato, +@c early or mid-1989! +un utente propose di aggiungere una funzione di traslitterazione a +@command{gawk}. +@c Wishing to avoid gratuitous new features, +@c at least theoretically +Il programma seguente @`e stato scritto per dimostrare che la traslitterazione +di caratteri poteva essere fatta con una funzione definita dall'utente. +Questo programma non @`e cos@`{@dotless{i}} completo come il programma di utilit@`a di sistema +@command{tr}, ma svolge buona parte dello stesso lavoro. + +Il programma @command{translate} @`e stato scritto molto prima che @command{gawk} +fosse in grado di separare ciascun carattere di una stringa in elementi +distinti di un vettore. Questo @`e il motivo per cui usa ripetutamente le +funzioni predefinite @code{substr()}, @code{index()}, e @code{gsub()} +(@pxref{Funzioni per stringhe}). +Ci sono due funzioni. La prima, @code{traduci_stringa()}, +richiede tre argomenti: + +@table @code +@item da +Una lista di caratteri da cui traslitterare + +@item a +Una lista di caratteri a cui traslitterare + +@item stringa +La stringa su cui effettuare la traslitterazione +@end table + +I vettori associativi facilitano molto la parte di traslitterazione. +@code{vettore_trad} contiene i caratteri ``a'', indicizzato dai +caratteri ``da''. Poi un semplice +ciclo scandisce @code{da}, un carattere alla volta. Per ogni carattere +in @code{da}, se il carattere compare in @code{stringa} +@`e rimpiazzato con il corrispondente carattere @code{a}. + +La funzione @code{traducilo()} chiama @code{traduci_stringa()}, usando @code{$0} +come stringa. Il programma principale imposta due variabili globali, @code{DA} e +@code{A}, dalla riga di comando, e poi modifica @code{ARGV} in modo che +@command{awk} legga dallo standard input. + +Infine, la regola di elaborazione si limita a chiamare @code{traducilo()} +per ogni record: + +@cindex @code{translate.awk}, programma +@cindex programma @code{translate.awk} +@example +@c file eg/prog/translate.awk +# translate.awk --- fa cose simili al comando tr +@c endfile +@ignore +@c file eg/prog/translate.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# August 1989 +# February 2009 - bug fix + +@c endfile +@end ignore +@c file eg/prog/translate.awk +# Bug: non gestisce cose del tipo tr A-Z a-z; deve essere +# descritto carattere per carattere. +# Tuttavia, se `a' @`e pi@`u corto di `da', +# l'ultimo carattere in `a' @`e usato per il resto di `da'. + +function traduci_stringa(da, a, stringa, lf, lt, lstringa, vettore_trad, + i, c, risultato) +@{ + lf = length(da) + lt = length(a) + lstringa = length(stringa) + for (i = 1; i <= lt; i++) + vettore_trad[substr(da, i, 1)] = substr(a, i, 1) + if (lt < lf) + for (; i <= lf; i++) + vettore_trad[substr(da, i, 1)] = substr(a, lt, 1) + for (i = 1; i <= lstringa; i++) @{ + c = substr(stringa, i, 1) + if (c in vettore_trad) + c = vettore_trad[c] + risultato = risultato c + @} + return risultato +@} + +function traducilo(da, a) +@{ + return $0 = traduci_stringa(da, a, $0) +@} + +# programma principale +BEGIN @{ +@group + if (ARGC < 3) @{ + print "sintassi: translate da a" > "/dev/stderr" + exit + @} +@end group + DA = ARGV[1] + A = ARGV[2] + ARGC = 2 + ARGV[1] = "-" +@} + +@{ + traducilo(DA, A) + print +@} +@c endfile +@end example + +@`E possibile effettuare la traslitterazione di caratteri in una funzione a +livello utente, ma non @`e detto che sia efficiente, e noi (sviluppatori +di @command{gawk}) abbiamo iniziato a prendere in considerazione l'aggiunta di una funzione. +Tuttavia, poco dopo aver scritto questo programma, abbiamo saputo che Brian +Kernighan aveva aggiunto le funzioni @code{toupper()} e @code{tolower()} alla +sua versione di @command{awk} (@pxref{Funzioni per stringhe}). Queste +funzioni gestiscono la maggior parte dei casi in cui serva la traslitterazione +di caratteri, e quindi abbiamo deciso di limitarci ad aggiungere le stesse +funzioni a @command{gawk}, e di disinteressarci del resto. + +Un miglioramento ovvio a questo programma sarebbe di impostare il vettore +@code{vettore_trad} solo una volta, in una regola @code{BEGIN}. Tuttavia, ci@`o +presuppone che le liste ``da'' e ``a'' non cambino mai durante tutta +l'esecuzione del programma. + +Un altro miglioramento ovvio @`e di consentire l'uso di intervalli, come +@samp{a-z}, come consentito dal programma di utilit@`a @command{tr}. Si pu@`o +trarre ispirazione dal codice di @file{cut.awk} (@pxref{Programma cut}). + + +@node Programma labels +@subsection Stampare etichette per lettere + +@cindex stampare etichette per lettera +@cindex etichette per lettera@comma{} stampare +Ecco un programma ``del mondo-reale''@footnote{``Del mondo-reale'' @`e definito +come ``un programma effettivamente usato per realizzare qualcosa''.}. +Questo script legge elenchi di nomi e indirizzi, e genera etichette per +lettera. Ogni pagina di etichette contiene 20 etichette, su due file da 10 +etichette l'una. Gli indirizzi non possono contenere pi@`u di cinque righe di +dati. Ogni indirizzo @`e separato dal successivo da una riga bianca. + +L'idea di base @`e di leggere dati per 20 etichette. Ogni riga di ogni etichetta +@`e immagazzinata nel vettore @code{riga}. L'unica regola si occupa di riempire +il vettore @code{riga} e di stampare la pagina dopo che sono state lette 20 +etichette. + +La regola @code{BEGIN} si limita a impostare @code{RS} alla stringa vuota, in +modo che @command{awk} divida un record dal successivo quando incontra una riga +bianca. +(@pxref{Record}). +Inoltre imposta @code{LIMITE_LINEE} a 100, +perch@'e 100 @`e il massimo numero di righe sulla pagina +@iftex +(@math{20 @cdot 5 = 100}). +@end iftex +@ifnottex +@ifnotdocbook +(20 * 5 = 100). +@end ifnotdocbook +@end ifnottex +@docbook +(20 ⋅ 5 = 100). +@end docbook + +Il grosso del lavoro @`e svolto nella funzione @code{stampa_pagina()}. +Le righe che compongono le etichette sono immagazzinate sequenzialmente nel vettore +@code{riga}. Ma occorre stamparle in +orizzontale: @code{riga[1]} a fianco di @code{riga[6]}, @code{riga[2]} a +fianco di @code{riga[7]}, e cos@`{@dotless{i}} via. Questo si pu@`o fare utilizzando due +cicli. Quello pi@`u esterno, controllato dalla variabile @code{i}, gestisce 10 +righe di dati, ovvero la stampa di due etichette una a fianco dell'altra. +Il ciclo pi@`u interno +controllato dalla variabile @code{j}, gestisce le singole righe che compongono +ognuno degli indirizzi. +Poich@'e @code{j} varia da 0 a 4, @samp{i+j} @`e la riga @code{j}-esima +dell'indirizzo di sinistra, e @samp{i+j+5} @`e quella stampata alla sua destra. +L'output @`e simile a quello mostrato qui sotto: + +@example +riga 1 riga 6 +riga 2 riga 7 +riga 3 riga 8 +riga 4 riga 9 +riga 5 riga 10 +@dots{} +@end example + +@noindent +La stringa di formato per @code{printf} @samp{%-41s} allinea a +sinistra i dati, e li stampa in un campo di lunghezza fissa. + +Come nota finale, un'ulteriore riga bianca extra viene stampata alle righe 21 e +61, per mantenere entro i bordi l'output sulle etichette. Ci@`o dipende dalla +particolare marca di etichette in uso quando il programma @`e stato scritto. +Si noti anche che ci sono due righe bianche a inizio pagina e due righe +bianche a fine pagina. + +La regola @code{END} si occupa di stampare l'ultima pagina di +etichette; @`e improbabile che il numero di indirizzi da stampare sia un +multiplo esatto di 20: + +@cindex @code{labels.awk}, programma +@cindex programma @code{labels.awk} +@example +@c file eg/prog/labels.awk +# labels.awk --- stampare etichette per lettera +@c endfile +@ignore +@c file eg/prog/labels.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# June 1992 +# December 2010, minor edits +@c endfile +@end ignore +@c file eg/prog/labels.awk + +# Ogni etichetta @`e 5 righe di dati, qualcuna delle quali pu@`o essere bianca. +# I fogli con le etichetta hanno 2 righe bianche in cima alla pagina e altre 2 +# a fine pagina. + +BEGIN @{ RS = "" ; LIMITE_LINEE = 100 @} + +function stampa_pagina( i, j) +@{ + if (NUMEROrighe <= 0) + return + + printf "\n\n" # in cima + + for (i = 1; i <= NUMEROrighe; i += 10) @{ + if (i == 21 || i == 61) + print "" + for (j = 0; j < 5; j++) @{ + if (i + j > LIMITE_LINEE) + break + printf " %-41s %s\n", riga[i+j], riga[i+j+5] + @} + print "" + @} + + printf "\n\n" # in fondo + + delete riga +@} + +# regola principale +@{ + if (contatore >= 20) @{ + stampa_pagina() + contatore = 0 + NUMEROrighe = 0 + @} + n = split($0, a, "\n") + for (i = 1; i <= n; i++) + riga[++NUMEROrighe] = a[i] + for (; i <= 5; i++) + riga[++NUMEROrighe] = "" + contatore++ +@} + +END @{ + stampa_pagina() +@} +@c endfile +@end example + +@node Programma utilizzo parole +@subsection Generare statistiche sulla frequenza d'uso delle parole + +@cindex parole, statistica utilizzo delle +@cindex statistica utilizzo delle parole + +Quando si lavora con una grande quantit@`a di testo, pu@`o essere interessante +sapere quanto spesso ricorrono le diverse parole. Per esempio, un autore pu@`o +fare un uso eccessivo di certe parole, e in questo caso si potrebbero +trovare sinonimi da sostituire a +parole che appaiono troppo spesso. +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SUBSECTION} spiega come +scrivere un programma per contare le parole e presentare in un formato +utile le informazioni relative alla loro frequenza. + +A prima vista, un programma come questo sembrerebbe essere sufficiente: + +@example +# wordfreq-first-try.awk --- stampa lista frequenze utilizzo parole + +@{ + for (i = 1; i <= NF; i++) + freq[$i]++ +@} + +END @{ + for (word in freq) + printf "%s\t%d\n", word, freq[word] +@} +@end example + +Il programma si affida al meccanismo con cui @command{awk} divide i campi per +default, per suddividere ogni riga in ``parole'' e usa un vettore associativo +di nome @code{freq}, che ha per indici le singole parole, per contare il +numero di volte che ogni parola viene usata. Nella regola @code{END}, stampa i +contatori. + +Questo programma ha parecchi problemi che lo rendono praticamente inutile +su file di testo reali: + +@itemize @value{BULLET} +@item +Il linguaggio @command{awk} considera i caratteri maiuscoli e minuscoli come +distinti (non equivalenti). Quindi, ``barista'' e ``Barista'' sono +considerate parole differenti. Questo non @`e un comportamento auspicabile, +perch@'e le parole iniziano con la lettera maiuscola se sono a inizio frase in +un testo normale, e un analizzatore di frequenze dovrebbe ignorare la +distinzione maiuscolo/minuscolo. + +@item +Le parole sono individuate usando la convenzione @command{awk} secondo cui i +campi sono separati solo da spazi bianchi. Altri caratteri nell'input +(tranne il ritorno a capo) non hanno alcun particolare significato per +@command{awk}. Questo significa che i segni di interpunzione sono visti come +parte di una parola. + +@item +L'output non @`e scritto in alcun ordine utile. Si @`e probabilmente pi@`u +interessati a sapere quali parole ricorrono pi@`u di frequente, o ad avere +una tabella in ordine alfabetico che mostra quante volte ricorre ogni parola. +@end itemize + +@cindex @command{sort}, programma di utilit@`a +@cindex programma di utilit@`a @command{sort} +Il primo problema si pu@`o risolvere usando @code{tolower()} per rimuovere la +distinzione maiuscolo/minuscolo. Il secondo problema si pu@`o risolvere usando +@code{gsub()} per rimuovere i caratteri di interpunzione. Infine, per +risolvere il terzo problema si pu@`o usare il programma di utilit@`a +@command{sort} per elaborare l'output dello script @command{awk}. Ecco la +nuova versione del programma: + +@cindex @code{wordfreq.awk}, programma +@cindex programma @code{wordfreq.awk} +@example +@c file eg/prog/wordfreq.awk +# wordfreq.awk --- stampa la lista con la frequenza delle parole + +@{ + $0 = tolower($0) # togli maiuscolo/minuscolo + # togli interpunzione + gsub(/[^[:alnum:]_[:blank:]]/, "", $0) + for (i = 1; i <= NF; i++) + freq[$i]++ +@} + +@c endfile +END @{ + for (word in freq) + printf "%s\t%d\n", word, freq[word] +@} +@end example + +La @dfn{regexp} @code{/[^[:alnum:]_[:blank:]]/} si poteva scrivere come +@code{/[[:punct:]]/}, ma in questo modo il caratteri trattino basso sarebbe +stato rimosso, mentre si desidera conservarlo. + +Supponendo di aver salvato questo programma in un file di nome +@file{wordfreq.awk}, +e che i dati siano in @file{file1}, il seguente comando con @dfn{pipeline}: + +@example +awk -f wordfreq.awk file1 | sort -k 2nr +@end example + +@noindent +produce una tabella delle parole che appaiono in @file{file1} in ordine +descrescente di frequenza. + +Il programma @command{awk} da solo gestisce adeguatamente i dati e produce +una tabella delle frequenza che non @`e ordinata. +L'output di @command{awk} @`e poi messo in ordine dal programma di utilit@`a +@command{sort} e stampato sullo schermo. + +Le opzioni passate a @command{sort} +richiedono un ordinamento che usi come chiave il secondo campo di ogni riga +in input (saltando il primo campo), che le chiavi di ordinamento siano +trattate come quantit@`a numeriche +(altrimenti @samp{15} sarebbe stampato prima di @samp{5}), e che l'ordinamento +sia fatto in ordine decrescente (inverso). + +Il comando @command{sort} potrebbe anche essere richiamato dall'interno del +programma, cambiando l'azione da fare nella regola @code{END} a: + +@example +@c file eg/prog/wordfreq.awk +END @{ + sort = "sort -k 2nr" + for (word in freq) + printf "%s\t%d\n", word, freq[word] | sort + close(sort) +@} +@c endfile +@end example + +Questa maniera di ordinare dev'essere usata su sistemi che non hanno delle +vere e proprie @dfn{pipe} a livello di riga di comando (o di procedura di +comandi). +Si veda la documentazione generale riguardo al sistema operativo per maggiori +informazioni su come usare il programma @command{sort}. + +@node Programma riordino diario +@subsection Eliminare duplicati da un file non ordinato + +@cindex righe, duplicate@comma{} rimuovere +@cindex rimuovere righe duplicate +Il programma @command{uniq} +(@pxref{Programma uniq}) +rimuove righe duplicate da dati @emph{ordinati}. + +Si supponga, tuttavia, di dover rimuovere righe duplicate da un @value{DF}, +ma di voler conservare l'ordine in cui le righe sono state scritte. Un buon +esempio di questo tipo potrebbe essere un file della cronologia dei comandi +della shell. Il file della cronologia dei comandi +mantiene copia di tutti i comandi che sono stati dati, e non @`e +insolito ripetere un comando molte volte di fila. Occasionalmente si +potrebbe voler compattare la cronologia togliendo le righe duplicate. +Tuttavia sarebbe opportuno mantenere l'ordine originale dei comandi. + +Questo semplice programma fa questo. Usa due vettori. Il vettore @code{dati} +ha come indice il testo di ogni riga. +Per ogni riga, @code{dati[$0]} @`e incrementato di uno. +Se una particolare riga non @`e stata ancora vista, @code{dati[$0]} @`e zero. +In tal caso, il testo della riga @`e immagazzinato in @code{righe[contatore]}. +Ogni elemento del vettore @code{righe} @`e un comando unico, e gli +indici di @code{righe} indicano l'ordine in cui quelle righe sono state +incontrate. +La regola @code{END} stampa semplicemente le righe, in ordine: + +@cindex Rakitzis, Byron +@cindex @code{histsort.awk}, programma +@cindex programma @code{histsort.awk} +@example +@c file eg/prog/histsort.awk +# histsort.awk --- compatta un file della cronologia dei comandi della shell +# Grazie a Byron Rakitzis per l'idea generale +@c endfile +@ignore +@c file eg/prog/histsort.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# May 1993 +@c endfile +@end ignore +@c file eg/prog/histsort.awk + +@group +@{ + if (dati[$0]++ == 0) + righe[++contatore] = $0 +@} +@end group + +@group +END @{ + for (i = 1; i <= contatore; i++) + print righe[i] +@} +@end group +@c endfile +@end example + +Questo programma pu@`o essere un punto di partenza per generare altre +informazioni utili. +Per esempio, usando la seguente istruzione @code{print} nella regola +@code{END} permette di sapere quante volte viene usato un certo comando: + +@example +print dati[righe[i]], righe[i] +@end example + +@noindent +Questo si pu@`o fare perch@'e @code{dati[$0]} @`e incrementato ogni volta che una +riga @`e stata trovata. + +@node Programma extract +@subsection Estrarre programmi da un file sorgente Texinfo + +@cindex Texinfo, estrarre programma da file sorgente +@cindex estrarre programma da file sorgente Texinfo +@cindex file Texinfo, estrarre programma da +@ifnotinfo +Sia questo capitolo che il precedente +(@ref{Funzioni di libreria}) +presentano un numero elevato di programmi @command{awk}. +@end ifnotinfo +@ifinfo +I nodi +@ref{Funzioni di libreria}, +e @ref{Programmi di esempio}, +sono nodi al livello pi@`u elevato, e +contengono nodi che descrivono un numero elevato di programmi @command{awk}. +@end ifinfo +Se si vuole fare pratica con questi programmi, @`e fastidioso doverli +digitare di nuovo manualmente. @`E per questo che abbiamo pensato a un programma +in grado di estrarre parti di un file in input Texinfo e metterli in file +separati. + +@cindex Texinfo +Questo @value{DOCUMENT} @`e scritto in @uref{http://www.gnu.org/software/texinfo/, Texinfo}, +il programma di formattazione di documenti del progetto GNU. +Un solo file sorgente Texinfo pu@`o essere usato per produrre sia la +documentazione stampata, usando @TeX{}, sia quella online. +@ifnotinfo +(Texinfo @`e esaurientemente documentato nel libro +@cite{Texinfo---The GNU Documentation Format}, +disponibile alla Free Software Foundation, +e anche @uref{http://www.gnu.org/software/texinfo/manual/texinfo/, online}.) +@end ifnotinfo +@ifinfo +(Il linguaggio Texinfo @`e descritto esaurientemente, a partire da +@inforef{Top, , Texinfo, texinfo,Texinfo---The GNU Documentation Format}.) +@end ifinfo + +Per quel che ci riguarda, @`e sufficiente sapere tre cose riguardo ai file di +input Texinfo: + +@itemize @value{BULLET} +@item +Il simbolo ``chiocciola'' (@samp{@@}) @`e speciale per +Texinfo, proprio come la barra inversa (@samp{\}) lo @`e per il linguaggio C +o per @command{awk}. I simboli @samp{@@} sono rappresentati nel sorgente +Texinfo come @samp{@@@@}. + +@item +I commenti iniziano con @samp{@@c} o con @samp{@@comment}. +Il programma di estrazione file funziona usando dei commenti speciali che +sono posti all'inizio di una riga. + +@item +Righe contenenti comandi @samp{@@group} e @samp{@@end group} racchiudono testi +di esempio che non dovrebbero andare a cavallo di due pagine. +(Sfortunatamente, @TeX{} non @`e sempre in grado di fare le cose in maniera +esatta, e quindi va un po' aiutato). +@end itemize + +Il programma seguente, @file{extract.awk}, legge un file sorgente Texinfo +e fa due cose, basandosi sui commenti speciali. +Dopo aver visto il commento @samp{@w{@@c system @dots{}}}, +esegue un comando, usando il testo del comando contenuto nella +riga di controllo e passandolo alla funzione @code{system()} +(@pxref{Funzioni di I/O}). +Dopo aver trovato il commento @samp{@@c file @var{nome_file}}, ogni riga +successiva @`e spedita al file @var{nome_file}, fino a che si trova un +commento @samp{@@c endfile}. +Le regole in @file{extract.awk} sono soddisfatte sia quando incontrano +@samp{@@c} che quando incontrano @samp{@@comment} e quindi la parte +@samp{omment} @`e opzionale. +Le righe che contengono @samp{@@group} e @samp{@@end group} sono semplicemente +ignorate. +@file{extract.awk} usa la funzione di libreria @code{join()} +(@pxref{Funzione join}). + +I programmi di esempio nel sorgente Texinfo online di @cite{@value{TITLE}} +(@file{gawktexi.in}) sono stati tutti inseriti tra righe @samp{file} e righe +@samp{endfile}. La distribuzione di @command{gawk} usa una copia di +@file{extract.awk} per estrarre i programmi di esempio e per installarne +molti in una particolare directory dove @command{gawk} li pu@`o trovare. +Il file Texinfo ha un aspetto simile a questo: + +@example +@dots{} +Questo programma ha una regola @@code@{BEGIN@} +che stampa un messaggio scherzoso: + +@@example +@@c file esempi/messages.awk +BEGIN @@@{ print "Non v'allarmate!" @@@} +@@c endfile +@@end example + +Stampa anche qualche avviso conclusivo: + +@@example +@@c file esempi/messages.awk +END @@@{ print "Evitate sempre gli archeologi annoiati!" @@@} +@@c endfile +@@end example +@dots{} +@end example + +Il programma @file{extract.awk} inizia con l'impostare @code{IGNORECASE} a +uno, in modo che un miscuglio di lettere maiuscole e minuscole nelle direttive +non faccia differenza. + +La prima regola gestisce le chiamate a @code{system()}, controllando che sia +stato fornito un comando (@code{NF} dev'essere almeno tre) e controllando +anche che il comando termini con un codice di ritorno uguale a zero, che sta +a significare che tutto @`e andato bene: + +@cindex @code{extract.awk}, programma +@cindex programma @code{extract.awk} +@example +@c file eg/prog/extract.awk +# extract.awk --- estrae file ed esegue programmi dal file Texinfo +@c endfile +@ignore +@c file eg/prog/extract.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# May 1993 +# Revised September 2000 +@c endfile +@end ignore +@c file eg/prog/extract.awk + +BEGIN @{ IGNORECASE = 1 @} + +/^@@c(omment)?[ \t]+system/ @{ + if (NF < 3) @{ + e = ("extract: " FILENAME ":" FNR) + e = (e ": riga `system' con formato errato") + print e > "/dev/stderr" + next + @} + $1 = "" + $2 = "" + stat = system($0) + if (stat != 0) @{ + e = ("extract: " FILENAME ":" FNR) + e = (e ": attenzione: system ha restituito " stat) + print e > "/dev/stderr" + @} +@} +@c endfile +@end example + +@noindent +La variabile @code{e} @`e stata usata per far s@`{@dotless{i}} che la regola +sia agevolemente contenuta nella @value{PAGE}. + +La seconda regola gestisce il trasferimento di dati in un file. Verifica che +nella direttiva sia stato fornito un @value{FN}. +Se il nome del file non @`e quello del file corrente, il file +corrente viene chiuso. Mantenere aperto il file corrente finch@'e non si trova +un nuovo nome file permette di usare la ridirezione @samp{>} per stampare i +contenuti nel file, semplificando la gestione dei file aperti. + +Il ciclo @code{for} esegue il lavoro. Legge le righe usando @code{getline} +(@pxref{Getline}). +Se si raggiunge una fine-file inattesa, viene chiamata la funzione +@code{@w{fine_file_inattesa()}}. Se la riga @`e una riga ``endfile'', +il ciclo viene abbandonato. +Se la riga inizia con @samp{@@group} o @samp{@@end group}, la riga viene +ignorata, e si passa a quella seguente. Allo stesso modo, eventuali commenti +all'interno degli esempi vengono ignorati. + +Il grosso del lavoro @`e nelle poche righe che seguono. Se la riga non ha +simboli @samp{@@}, il programma la pu@`o +stampare cos@`{@dotless{i}} com'@`e. Altrimenti, ogni @samp{@@} a inizio parola dev'essere +eliminato. +Per rimuovere i simboli @samp{@@}, la riga viene divisa nei singoli elementi +del vettore @code{a}, usando la funzione @code{split()} +(@pxref{Funzioni per stringhe}). +Il simbolo @samp{@@} @`e usato come carattere di separazione. +Ogni elemento del vettore @code{a} che risulti vuoto indica due caratteri +@samp{@@} contigui nella riga originale. Per ogni due elementi vuoti +(@samp{@@@@} nel file originale), va inserito un solo simbolo @samp{@@} nel +file in output. + +Una volta terminato di esaminare il vettore, viene chiamata la funzione @code{join()} +specificando nella chiamata il valore di @code{SUBSEP} +(@pxref{Vettori multidimensionali}), +per riunire nuovamente i pezzi in una riga sola. +La riga @`e poi stampata nel file di output: + +@example +@c file eg/prog/extract.awk +/^@@c(omment)?[ \t]+file/ @{ + if (NF != 3) @{ + e = ("extract: " FILENAME ":" FNR ": riga `file' con formato errato") + print e > "/dev/stderr" + next + @} + if ($3 != file_corrente) @{ + if (file_corrente != "") + close(file_corrente) + file_corrente = $3 + @} + + for (;;) @{ + if ((getline riga) <= 0) + fine_file_inattesa() + if (riga ~ /^@@c(omment)?[ \t]+endfile/) + break + else if (riga ~ /^@@(end[ \t]+)?group/) + continue + else if (riga ~ /^@@c(omment+)?[ \t]+/) + continue + if (index(riga, "@@") == 0) @{ + print riga > file_corrente + continue + @} + n = split(riga, a, "@@") + # if a[1] == "", vuol dire riga che inizia per @@, + # non salvare un @@ + for (i = 2; i <= n; i++) @{ + if (a[i] == "") @{ # era un @@@@ + a[i] = "@@" + if (a[i+1] == "") + i++ + @} + @} + print join(a, 1, n, SUBSEP) > file_corrente + @} +@} +@c endfile +@end example + +@`E importante notare l'uso della ridirezione @samp{>} . +L'output fatto usando @samp{>} apre il file solo la prima volta; il file resta +poi aperto, e ogni scrittura successiva @`e aggiunta in fondo al file. +(@pxref{Ridirezione}). +Ci@`o rende possibile mischiare testo del programm e commenti esplicativi +(come @`e stato fatto qui) nello stesso file sorgente, senza nessun problema. +Il file viene chiuso solo quando viene trovato un nuovo nome di +@value{DF} oppure alla fine del file in input. + +Per finire, la funzione @code{@w{fine_file_inattesa()}} stampa un +appropriato messaggio di errore ed esce. +La regola @code{END} gestisce la pulizia finale, chiudendo il file aperto: + +@example +@c file eg/prog/extract.awk +@group +function fine_file_inattesa() +@{ + printf("extract: %s:%d: fine-file inattesa, o errore\n", + FILENAME, FNR) > "/dev/stderr" + exit 1 +@} +@end group + +END @{ + if (file_corrente) + close(file_corrente) +@} +@c endfile +@end example + +@node Programma sed semplice +@subsection Un semplice editor di flusso + +@cindex @command{sed}, programma di utilit@`a +@cindex programma di utilit@`a @command{sed} +@cindex editori di flusso +@cindex flusso, editori di +Il programma di utilit@`a @command{sed} @`e un @dfn{editore di flusso}, +ovvero un programma che legge un flusso di dati, lo modifica, e scrive il file +cos@`{@dotless{i}} modificato. +@`E spesso usato per fare modifiche generalizzate a un grosso file, o a un +flusso di dati generato da una @dfn{pipeline} di comandi. +Sebbene @command{sed} sia un programma piuttosto complesso di suo, l'uso che +se ne fa solitamente @`e di effettuare delle sostituzioni globali attraverso +una @dfn{pipeline}: + +@example +@var{comando1} < dati.originali | sed 's/vecchio/nuovo/g' | @var{comando2} > risultato +@end example + +Qui, @samp{s/vecchio/nuovo/g} chiede a @command{sed} di ricercare la +@dfn{regexp} @samp{vecchio} in ogni riga di input e di sostituirla +dappertutto con il testo @samp{nuovo} (cio@`e, in tutte le occorrenze di +ciascuna riga). Questo @`e simile a quello che fa la funzione di @command{awk} +@code{gsub()} +(@pxref{Funzioni per stringhe}). + +Il programma seguente, @file{awksed.awk}, accetta almeno due argomenti dalla +riga di comando: l'espressione da ricercare e il testo con cui rimpiazzarla. +Ogni ulteriore argomento @`e considerato +come un nome di @value{DF} da elaborare. Se non ne viene fornito alcuno, si +usa lo standard input: + +@cindex Brennan, Michael +@cindex @command{awksed.awk}, programma +@cindex programma @command{awksed.awk} +@c @cindex simple stream editor +@c @cindex stream editor, simple +@example +@c file eg/prog/awksed.awk +# awksed.awk --- fa s/pippo/pluto/g usando solo print +# Ringraziamenti a Michael Brennan per l'idea +@c endfile +@ignore +@c file eg/prog/awksed.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# August 1995 +@c endfile +@end ignore +@c file eg/prog/awksed.awk + +function sintassi() +@{ + print "sintassi: awksed espressione rimpiazzo [file...]" > "/dev/stderr" + exit 1 +@} + +BEGIN @{ + # valida argomenti + if (ARGC < 3) + sintassi() + + RS = ARGV[1] + ORS = ARGV[2] + + # non usare argomenti come nomi di file + ARGV[1] = ARGV[2] = "" +@} + +@group +# guarda, mamma, senza mani! +@{ + if (RT == "") + printf "%s", $0 + else + print +@} +@end group +@c endfile +@end example + +Il programma fa assegnamento sulla capacit@`a di @command{gawk} di avere come +@code{RS} una @dfn{regexp}, +e anche sul fatto che @code{RT} viene impostato al testo che effettivamente +delimita il record (@pxref{Record}). + +L'idea @`e di usare @code{RS} come espressione da ricercare. @command{gawk} +automaticamente imposta @code{$0} al testo che compare tra due corrispondenze +all'espressione di ricerca. +Questo @`e appunto il testo che vogliamo conservare inalterato. Quindi, +impostando @code{ORS} al testo che si vuole sostituire, una semplice +istruzione @code{print} scrive il testo che si vuole mantenere, seguito dal +testo che si vuole invece sostituire. + +C'@`e un problema in questo schema, ossia cosa fare se l'ultimo record +non termina con un testo che corrisponde a @code{RS}. Usando un'istruzione +@code{print} incondizionatamente stampa il testo da sostituire, il che non +@`e corretto. +Tuttavia, se il file non termina con del testo che corrisponde a @code{RS}, +@code{RT} @`e impostata alla stringa nulla. In tal caso, si pu@`o stampare +@code{$0} usando @code{printf} +(@pxref{Printf}). + +La regola @code{BEGIN} gestisce la preparazione, controllando che ci sia +il numero giusto di argomenti e chiamando @code{sintassi()} se c'@`e un problema. +Poi imposta @code{RS} e @code{ORS} dagli argomenti della riga di comando e +imposta @code{ARGV[1]} e @code{ARGV[2]} alla stringa nulla, per impedire che +vengano considerati dei @value{FNS} +(@pxref{ARGC e ARGV}). + +La funzione @code{sintassi()} stampa un messaggio di errore ed esce. +Per finire, l'unica regola gestisce lo schema di stampa delineato pi@`u sopra, +usando @code{print} o @code{printf} come richiesto, a seconda del valore di +@code{RT}. + +@node Programma igawk +@subsection Una maniera facile per usare funzioni di libreria + +@cindex libreria di funzioni @command{awk}, programma di esempio per usare +@cindex funzioni, librerie di, programma di esempio per usare +@iftex +Nella +@end iftex +@ifnottex +In +@end ifnottex +@ref{Includere file}, abbiamo visto come @command{gawk} preveda la +possibilit@`a di includere file. Tuttavia, questa @`e un'estensione @command{gawk}. +Questa @value{SECTION} evidenzia l'utilit@`a di rendere l'inclusione di +file disponibile per @command{awk} standard, e mostra come farlo utilizzando +una combinazione di programmazione di shell e di @command{awk}. + +Usare funzioni di libreria in @command{awk} pu@`o presentare molti vantaggi. +Incoraggia il riutilizzo di codice e la scrittura di funzioni di tipo +generale. I programmi sono pi@`u snelli e quindi pi@`u comprensibili. +Tuttavia, usare funzioni di libreria @`e facile solo in fase di scrittura di +programmi @command{awk}; @`e invece complicato al momento di eseguirli, +rendendo necessario specificare molte opzioni @option{-f}. Se @command{gawk} +non @`e disponibile, non lo sono neppure la variabile d'ambiente @env{AWKPATH} e +la possibilit@`a di conservare funzioni @command{awk} in una directory di +libreria (@pxref{Opzioni}). +Sarebbe bello poter scrivere programmi nel modo seguente: + +@example +# funzioni di libreria +@@include getopt.awk +@@include join.awk +@dots{} + +# programma principale +BEGIN @{ + while ((c = getopt(ARGC, ARGV, "a:b:cde")) != -1) + @dots{} + @dots{} +@} +@end example + +Il programma seguente, @file{igawk.sh}, fornisce questo servizio. +Simula la ricerca da parte di @command{gawk} della variabile d'ambiente +@env{AWKPATH} e permette anche delle inclusioni @dfn{nidificate} (cio@`e, +un file che @`e stato incluso tramite +@code{@@include} pu@`o contenere ulteriori istruzioni @code{@@include}). +@command{igawk} tenta di includere ogni file una volta sola, in modo che delle +inclusioni nidificate non contengano accidentalmente una funzione di libreria +pi@`u di una volta. + +@command{igawk} dovrebbe comportarsi esternamente proprio come @command{gawk}. +Questo vuol dire che dovrebbe accettare sulla riga di comando tutti gli +argomenti di @command{gawk}, compresa +la capacit@`a di specificare pi@`u file +sorgenti tramite l'opzione @option{-f} +e la capacit@`a di mescolare istruzioni da riga di comando e file di sorgenti di +libreria. + +Il programma @`e scritto usando il linguaggio della Shell POSIX +(@command{sh}).@footnote{Una spiegazione dettagliata del linguaggio della +@command{sh} non rientra negli intenti di questo libro. Qualche spiegazione +sommaria viene fornita, ma se si desidera una comprensione pi@`u dettagliata, si +dovrebbe consultare un buon libro sulla programmazione della shell.} +Il funzionamento @`e il seguente: + +@enumerate +@item +Esegue un ciclo attraverso gli argomenti, salvando tutto ci@`o che non si presenta come +codice sorgente @command{awk}, per quando il programma espanso sar@`a eseguito. + +@item +Per ogni argomento che rappresenta del codice @command{awk}, mette l'argomento +in una variabile di shell che verr@`a espansa. Ci sono due casi: + +@enumerate a +@item +Un testo letterale, fornito con l'opzione @option{-e} o @option{--source}. +Questo testo viene aggiunto direttamente in fondo. + +@item +@value{FNS} sorgenti, forniti con l'opzione @option{-f}. Usiamo il trucchetto +di aggiungere @samp{@@include @var{nome_file}} in fondo ai contenuti della +variabile di shell. Poich@'e il programma di inclusione dei file funziona +allo stesso modo in cui funziona @command{gawk}, ne risulta che il file viene +incluso nel programma al punto giusto. +@end enumerate + +@item +Esegue un programma (naturalmente @command{awk}) sui contenuti della variabile +di shell per espandere le istruzioni +@code{@@include}. Il programma espanso @`e messo in una seconda variabile di +shell. + +@item +Esegue il programma espanso richiamando @command{gawk} e tutti gli altri +argomenti originalmente forniti dall'utente sulla riga di comando (come p.es. +dei nomi di @value{DF}). +@end enumerate + +Questo programma usa variabili di shell in quantit@`a: per immagazzinare +argomenti della riga di comando e +il testo del programma @command{awk} che espander@`a il programma dell'utente, +per il programma originale dell'utente e per il programma espanso. Questo +modo di procedere risolve potenziali +problemi che potrebbero presentarsi se si usassero invece dei file temporanei, +ma rende lo script un po' pi@`u complicato. + +La parte iniziale del programma attiva il tracciamento della shell se il primo +argomento @`e @samp{debug}. + +La parte successiva esegue un ciclo che esamina ogni argomento della riga di +comando. +Ci sono parecchi casi da esaminare: + +@c @asis for docbook +@table @asis +@item @option{--} +Quest'opzione termina gli argomenti per @command{igawk}. Tutto quel che segue +dovrebbe essere passato al programma @command{awk} dell'utente senza essere +preso in considerazione. + +@item @option{-W} +Questo indica che l'opzione successiva @`e propria di @command{gawk}. Per +facilitare l'elaborazione degli argomenti, l'opzione @option{-W} @`e aggiunta +davanti agli argomenti rimanenti, e il +ciclo continua. (Questo @`e un trucco di programmazione della @command{sh}. +Non @`e il caso di preoccuparsene se non si ha familiarit@`a con il comando +@command{sh}.) + +@item @option{-v}, @option{-F} +Queste opzioni sono conservate e lasciate da gestire a @command{gawk}. + +@item @option{-f}, @option{--file}, @option{--file=}, @option{-Wfile=} +Il @value{FN} @`e aggiunto alla variabile di shell @code{programma}, insieme +a un'istruzione @code{@@include}. +Il programma di utilit@`a @command{expr} @`e usato per eliminare la parte +iniziale dell'argomento (p.es., @samp{--file=}). +(La sintassi tipica di @command{sh} richiederebbe di usare il comando +@command{echo} e il programma di utilit@`a @command{sed} per far questo. +Sfortunatamente, alcune versioni di @command{echo} valutano le sequenze +di protezione contenute nei loro argomenti, e questo potrebbe finire per +alterare il testo del programma. +L'uso di @command{expr} evita questo problema.) + +@item @option{--source}, @option{--source=}, @option{-Wsource=} +Il testo sorgente @`e aggiunto in fondo a @code{programma}. + +@item @option{--version}, @option{-Wversion} +@command{igawk} stampa il proprio numero di versione, esegue +@samp{gawk --version} per ottenere l'informazione relativa alla versione di +@command{gawk}, ed esce. +@end table + +Se nessuno degli argomenti +@option{-f}, @option{--file}, @option{-Wfile}, @option{--source}, +o @option{-Wsource} @`e stato fornito, il primo argomento che non @`e un'opzione +dovrebbe essere il programma @command{awk}. Se non ci sono argomenti rimasti +sulla riga di comando, @command{igawk} stampa un messaggio di errore ed esce. +Altrimenti, il primo argomento @`e aggiunto in fondo a @code{programma}. +In qualsiasi caso, dopo che gli argomenti sono stati elaborati, +la variabile di shell +@code{programma} contiene il testo completo del programma originale +@command{awk}. + +Il programma @`e il seguente: + +@cindex @code{igawk.sh}, programma +@cindex programma @code{igawk.sh} +@example +@c file eg/prog/igawk.sh +#! /bin/sh +# igawk --- come gawk ma abilita l'uso di @@include +@c endfile +@ignore +@c file eg/prog/igawk.sh +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# July 1993 +# December 2010, minor edits +@c endfile +@end ignore +@c file eg/prog/igawk.sh + +if [ "$1" = debug ] +then + set -x + shift +fi + +# Un ritorno a capo letterale, +# per formattare correttamente il testo del programma +n=' +' + +# Inizializza delle variabili alla stringa nulla +programma= +opts= + +while [ $# -ne 0 ] # ciclo sugli argomenti +do + case $1 in + --) shift + break ;; + + -W) shift + # Il costrutto $@{x?'messaggio qui'@} stampa un + # messaggio diagnostico se $x @`e la stringa nulla + set -- -W"$@{@@?'manca operando'@}" + continue ;; + + -[vF]) opts="$opts $1 '$@{2?'manca operando'@}'" + shift ;; + + -[vF]*) opts="$opts '$1'" ;; + + -f) programma="$programma$n@@include $@{2?'manca operando'@}" + shift ;; + + -f*) f=$(expr "$1" : '-f\(.*\)') + programma="$programma$n@@include $f" ;; + + -[W-]file=*) + f=$(expr "$1" : '-.file=\(.*\)') + programma="$programma$n@@include $f" ;; + + -[W-]file) + programma="$programma$n@@include $@{2?'manca operando'@}" + shift ;; + + -[W-]source=*) + t=$(expr "$1" : '-.source=\(.*\)') + programma="$programma$n$t" ;; + + -[W-]source) + programma="$programma$n$@{2?'manca operando'@}" + shift ;; + + -[W-]version) + echo igawk: version 3.0 1>&2 + gawk --version + exit 0 ;; + + -[W-]*) opts="$opts '$1'" ;; + + *) break ;; + esac + shift +done + +if [ -z "$programma" ] +then + programma=$@{1?'manca programma'@} + shift +fi + +# A questo punto, `programma' contiene il programma. +@c endfile +@end example + +Il programma @command{awk} che elabora le direttive @code{@@include} +@`e immagazzinato nella variabile di shell @code{progr_che_espande}. Ci@`o serve +a mantenere leggibile lo script. Questo programma @command{awk} legge +tutto il programma dell'utente, una riga per volta, usando @code{getline} +(@pxref{Getline}). I @value{FNS} in input e le istruzioni @code{@@include} +sono gestiti usando una pila. Man mano che viene trovata una @code{@@include}, +il valore corrente di @value{FN} @`e +``spinto'' sulla pila e il file menzionato nella direttiva @code{@@include} +diventa il @value{FN} corrente. Man mano che un file @`e finito, +la pila viene ``disfatta'', e il precedente file in input diventa nuovamente il +file in input corrente. Il processo viene iniziato ponendo il file originale +come primo file sulla pila. + +La funzione @code{percorso()} trova qual @`e il percorso completo di un file. +Simula il comportamento di @command{gawk} quando utilizza la variabile +d'ambiente @env{AWKPATH} +(@pxref{AWKPATH (Variabile)}). +Se un @value{FN} contiene una @samp{/}, non viene effettuata la ricerca del +percorso. Analogamente, se il +@value{FN} @`e @code{"-"}, viene usato senza alcuna modifica. Altrimenti, +il @value{FN} @`e concatenato col nome di ogni directory nella lista dei +percorsi, e vien fatto un tentativo per aprire il @value{FN} cos@`{@dotless{i}} generato. +Il solo modo di controllare se un file @`e leggibile da @command{awk} @`e di +andare avanti e tentare di leggerlo con +@code{getline}; questo @`e quel che +@code{percorso()} fa.@footnote{In alcune versioni molto datate di +@command{awk}, il test @samp{getline da_buttare < t} pu@`o ripetersi in un ciclo +infinito se il file esiste ma @`e vuoto.} +Se il file pu@`o essere letto, viene chiuso e viene restituito il valore di +@value{FN}: + +@ignore +An alternative way to test for the file's existence would be to call +@samp{system("test -r " t)}, which uses the @command{test} utility to +see if the file exists and is readable. The disadvantage to this method +is that it requires creating an extra process and can thus be slightly +slower. +@end ignore + +@example +@c file eg/prog/igawk.sh +progr_che_espande=' + +function percorso(file, i, t, da_buttare) +@{ + if (index(file, "/") != 0) + return file + + if (file == "-") + return file + + for (i = 1; i <= n_dir; i++) @{ + t = (lista_percorsi[i] "/" file) +@group + if ((getline da_buttare < t) > 0) @{ + # found it + close(t) + return t + @} +@end group + @} + return "" +@} +@c endfile +@end example + +Il programma principale @`e contenuto all'interno di una regola @code{BEGIN}. +La prima cosa che fa @`e di impostare il vettore @code{lista_percorsi} usato +dalla funzione @code{percorso()}. Dopo aver diviso la lista usando come +delimitatore @samp{:}, gli elementi nulli sono sostituiti da @code{"."}, +che rappresenta la directory corrente: + +@example +@c file eg/prog/igawk.sh +BEGIN @{ + percorsi = ENVIRON["AWKPATH"] + n_dir = split(percorsi, lista_percorsi, ":") + for (i = 1; i <= n_dir; i++) @{ + if (lista_percorsi[i] == "") + lista_percorsi[i] = "." + @} +@c endfile +@end example + +La pila @`e inizializzata con @code{ARGV[1]}, che sar@`a @code{"/dev/stdin"}. +Il ciclo principale viene subito dopo. Le righe in input sono lette una dopo +l'altra. Righe che non iniziano con @code{@@include} sono stampate cos@`{@dotless{i}} come +sono. +Se la riga inizia con @code{@@include}, il @value{FN} @`e in @code{$2}. +La funzione @code{percorso()} @`e chiamata per generare il percorso completo. +Se questo non riesce, il programma stampa un messaggio di errore e continua. + +Subito dopo occorre controllare se il file sia gi@`a stato incluso. Il vettore +@code{gia_fatto} @`e indicizzato dal nome completo di ogni @value{FN} incluso +e tiene traccia per noi di questa informazione. Se un file viene visto pi@`u +volte, viene stampato un messaggio di avvertimento. Altrimenti il nuovo +@value{FN} @`e aggiunto alla pila e l'elaborazione continua. + +Infine, quando @code{getline} giunge alla fine del file in input, il file +viene chiuso, e la pila viene elaborata. Quando @code{indice_pila} @`e minore +di zero, il programma @`e terminato: + +@example +@c file eg/prog/igawk.sh + indice_pila = 0 + input[indice_pila] = ARGV[1] # ARGV[1] @`e il primo file + + for (; indice_pila >= 0; indice_pila--) @{ + while ((getline < input[indice_pila]) > 0) @{ + if (tolower($1) != "@@include") @{ + print + continue + @} + cammino = percorso($2) +@group + if (cammino == "") @{ + printf("igawk: %s:%d: non riesco a trovare %s\n", + input[indice_pila], FNR, $2) > "/dev/stderr" + continue + @} +@end group + if (! (cammino in gia_fatto)) @{ + gia_fatto[cammino] = input[indice_pila] + input[++indice_pila] = cammino # aggiungilo alla pila + @} else + print $2, "incluso in", input[indice_pila], + "era gi@`a incluso in", + gia_fatto[cammino] > "/dev/stderr" + @} + close(input[indice_pila]) + @} +@}' # l'apice chiude la variabile `progr_che_espande' + +programma_elaborato=$(gawk -- "$progr_che_espande" /dev/stdin << EOF +$programma +EOF +) +@c endfile +@end example + +Il costrutto di shell @samp{@var{comando} << @var{marcatore}} @`e chiamato +@dfn{here document} (@dfn{documento sul posto}). Ogni riga presente nello +script di shell fino al @var{marcatore} @`e passato in input a @var{comando}. +La shell elabora i contenuti dell'@dfn{here document} sostituendo, dove serve, +variabili e comandi (ed eventualmente altre cose, a seconda della shell +in uso). + +Il costrutto di shell @samp{$(@dots{})} @`e chiamato @dfn{sostituzione di comando}. +L'output del comando posto all'interno delle parentesi @`e sostituito +nella riga di comando. +Poich@'e il risultato @`e usato in un assegnamento di variabile, +viene salvato come un'unica stringa di caratteri, anche se il risultato +contiene degli spazi bianchi. + +Il programma espanso @`e salvato nella variabile @code{programma_elaborato}. +Il tutto avviene secondo le fasi seguenti: + +@enumerate +@item +Si esegue @command{gawk} con il programma che gestisce le @code{@@include} +(il valore della variabile di shell +@code{progr_che_espande}) leggendo lo standard input. + +@item +Lo standard input contiene il programma dell'utente, +nella variabile di shell @code{programma}. +L'input @`e passato a @command{gawk} tramite un @dfn{here document}. + +@item +I risultati di questo processo sono salvati nella variabile di shell +@code{programma_elaborato} usando la sostituzione di comando. +@end enumerate + +L'ultima fase @`e la chiamata a @command{gawk} con il programma espanso, +insieme alle opzioni originali e agli argomenti della riga di comando che +l'utente aveva fornito: + +@example +@c file eg/prog/igawk.sh +eval gawk $opts -- '"$programma_elaborato"' '"$@@"' +@c endfile +@end example + +Il comando @command{eval} @`e una struttura della shell che riesegue +l'elaborazione dei parametri della riga di comando. Gli apici proteggono le +parti restanti. + +Questa versione di @command{igawk} @`e la quinta versione di questo programma. +Ci sono quattro semplificazioni migliorative: + +@itemize @value{BULLET} +@item +L'uso di @code{@@include} anche per i file specificati tramite l'opzione +@option{-f} consente di semplificare di molto la preparazione del programma +iniziale @command{awk}; tutta l'elaborazione delle istruzioni @code{@@include} +pu@`o essere svolta in una sola volta. + +@item +Non tentare di salvare la riga letta tramite @code{getline} all'interno della +funzione @code{percorso()} quando si controlla se il file @`e accessibile +per il successivo uso nel programma principale semplifica notevolmente +le cose. + +@item +Usare un ciclo di @code{getline} nella regola @code{BEGIN} rende possibile +fare tutto in un solo posto. Non @`e necessario programmare un ulteriore ciclo +per elaborare le istruzioni @code{@@include} nidificate. + +@item +Invece di salvare il programma espanso in un file temporaneo, assegnarlo a +una variabile di shell evita alcuni potenziali problemi di sicurezza. +Ci@`o per@`o ha lo svantaggio di basare lo script su funzionalit@`a del +linguaggio @command{sh}, il che rende pi@`u difficile la comprensione a chi non +abbia familiarit@`a con il comando +@command{sh}. +@end itemize + +Inoltre, questo programma dimostra come spesso valga la pena di utilizzare +insieme la programmazione della @command{sh} e quella di @command{awk}. +Solitamente, si pu@`o fare parecchio senza dover ricorrere alla programmazione +di basso livello in C o C++, ed @`e spesso pi@`u facile fare certi tipi di +manipolazioni di stringhe e argomenti usando la shell, piuttosto che +@command{awk}. + +Infine, @command{igawk} dimostra che non @`e sempre necessario aggiungere nuove +funzionalit@`a a un programma; queste possono spesso essere aggiunte in +cima.@footnote{@command{gawk} +@`e in grado di elaborare istruzioni @code{@@include} al suo stesso interno, per +permettere l'uso di programmi @command{awk} come script Web CGI.} + + +@node Programma anagram +@subsection Trovare anagrammi da una lista di parole + +@cindex anagrammi, trovare +Un'interessante sfida per il programmatore @`e quella di cercare @dfn{anagrammi} in una +lista di parole (come +@file{/usr/share/dict/italian} presente in molti sistemi GNU/Linux). +Una parola @`e un anagramma di un'altra se entrambe le parole contengono +le stesse lettere +(p.es., ``branzino'' e ``bronzina''). + +La Colonna 2, Problema C, della seconda edizione del libro di Jon Bentley +@cite{Programming Pearls}, presenta un algoritmo elegante. +L'idea @`e di assegnare a parole che sono anagrammi l'una dell'altra una +firma comune, e poi di ordinare tutte le parole in base alla loro +firma e di stamparle. +Il Dr.@: Bentley fa notare che prendere tutte le lettere di ogni parola ed +elencarle in ordine alfabetico produce queste firme comuni. + +Il programma seguente usa vettori di vettori per riunire +parole con la stessa firma, e l'ordinamento di vettori per stampare le +parole trovate in ordine alfabetico: + +@cindex @code{anagram.awk}, programma +@cindex programma @code{anagram.awk} +@example +@c file eg/prog/anagram.awk +# anagram.awk --- Un'implementazione dell'algoritmo per trovare anagrammi +# dalla seconda edizione +# del libro di Jon Bentley "Programming Pearls". +# Addison Wesley, 2000, ISBN 0-201-65788-0. +# Colonna 2, Problema C, sezione 2.8, pp 18-20. +@c endfile +@ignore +@c file eg/prog/anagram.awk +# +# Questo programma richiede gawk 4.0 o una versione successiva. +# Funzionalit@`a di gawk richieste: +# - veri vettori multidimensionali +# - split() con separatore "" per separare ogni singolo carattere +# - le funzioni asort() e asorti() +# +# Vedere http://savannah.gnu.org/projects/gawk. +# +# Arnold Robbins +# arnold@@skeeve.com +# Public Domain +# January, 2011 +@c endfile +@end ignore +@c file eg/prog/anagram.awk + +/'s$/ @{ next @} # Salta i genitivi sassoni +@c endfile +@end example + +Il programma inizia con un'intestazione, e poi una regola per saltare +i genitivi sassoni eventualmente contenuti nel file che contiene la lista di +parole. La regola +successiva costruisce la struttura dei dati. Il primo indice del vettore +@`e rappresentato dalla firma; il secondo @`e la parola stessa: + +@example +@c file eg/prog/anagram.awk +@{ + chiave = da_parola_a_chiave($1) # costruisce la firma + data[chiave][$1] = $1 # Immagazzina parola con questa firma +@} +@c endfile +@end example + +La funzione @code{da_parola_a_chiave()} crea la firma. +Divide la parola in lettere singole, mette in ordine alfabetico le lettere, +e poi le rimette ancora insieme: + +@example +@c file eg/prog/anagram.awk +# da_parola_a_chiave --- divide parole in lettere, ordina e riunisce + +function da_parola_a_chiave(parola, a, i, n, risultato) +@{ + n = split(parola, a, "") + asort(a) + + for (i = 1; i <= n; i++) + risultato = risultato a[i] + + return risultato +@} +@c endfile +@end example + +Infine, la regola @code{END} percorre tutto il vettore e stampa +le liste degli anagrammi. L'output @`e poi passato al +comando di sistema @command{sort} perch@'e altrimenti gli +anagrammi sarebbero elencati in ordine arbitrario: + +@example +@c file eg/prog/anagram.awk +END @{ + sort = "sort" + for (chiave in data) @{ + # ordina parole con la stessa chiave + n_parole = asorti(data[chiave], parole) + if (n_parole == 1) + continue + + # e stampa. Problema minore: uno spazio extra a fine di ogni riga + for (j = 1; j <= n_parole; j++) + printf("%s ", parole[j]) | sort + print "" | sort + @} + close(sort) +@} +@c endfile +@end example + +Ecco una piccola parte dell'output quando il programma @`e eseguito: + +@example +$ @kbd{gawk -f anagram.awk /usr/share/dict/italian | grep '^b'} +@dots{} +baraste bastare serbata +barasti basarti +baratro tabarro +barattoli ribaltato tribolata +barbieri birberia +barche brache +barcollerei corbelleria +bare erba +bareremmo brameremo +barili librai +@dots{} +@end example + + +@node Programma signature +@subsection E ora per qualcosa di completamente differente + +@cindex @code{signature}, programma +@cindex programma @code{signature} +@cindex Brini, Davide +Il programma seguente @`e stato scritto da Davide Brini +@c (@email{dave_br@@gmx.com}) +ed @`e pubblicato sul @uref{http://backreference.org/2011/02/03/obfuscated-awk/, +suo sito web}. +Serve come sua firma nel gruppo Usenet @code{comp.lang.awk}. +Questi sono i termini da lui stabiliti per il copyright: + +@quotation +Copyright @copyright{} 2008 Davide Brini + +Copying and distribution of the code published in this page, with or without +modification, are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. +@end quotation + +Ecco il programma: + +@example +awk 'BEGIN@{O="~"~"~";o="=="=="==";o+=+o;x=O""O;while(X++<=x+o+o)c=c"%c"; +printf c,(x-O)*(x-O),x*(x-o)-o,x*(x-O)+x-O-o,+x*(x-O)-x+o,X*(o*o+O)+x-O, +X*(X-x)-o*o,(x+X)*o*o+o,x*(X-x)-O-O,x-O+(O+o+X+x)*(o+O),X*X-X*(x-O)-x+O, +O+X*(o*(o+O)+O),+x+O+X*o,x*(x-o),(o+X+x)*o*o-(x-O-O),O+(X-x)*(X+O),x-O@}' +@end example +@c genera l'email del tizio: +@c dave_br@gmx.com + +@cindex Johansen, Chris +Viene lasciato al lettore il piacere di stabilire cosa fa il programma. +(Se si @`e sull'orlo della disperazione nel tentativo di comprensione, si veda +la spiegazione di Chris Johansen, +che @`e contenuta nel file sorgente Texinfo di questo @value{DOCUMENT}.) + +@ignore +To: "Arnold Robbins" <arnold@skeeve.com> +Date: Sat, 20 Aug 2011 13:50:46 -0400 +Subject: The GNU Awk User's Guide, Section 13.3.11 +From: "Chris Johansen" <johansen@main.nc.us> +Message-ID: <op.v0iw6wlv7finx3@asusodin.thrudvang.lan> + +Arnold, tu non mi conosci, ma c'@`e un sottile legame tra noi. Mia moglie @`e +Barbara A. Field, FAIA, GIT '65 (B. Arch.). + +Ho un paio di copie cartacee di "Effective Awk Programming" da +anni, ed ora sto leggendo di nuovo la versione Kindle di "The GNU Awk User's +Guide". Quando sono arrivato alla sezione 13.3.11, ho riformattato e +brevemente commentato lo script di firma di Davide Brin per comprenderne il funzionamento. + +Mi pare che questo possa avere un valore pedagogico come esempio +(sia pure imperfetto) del significato di spazi bianchi e commenti, e un +punto di partenza per una tale discussione. Sicuramente ha aiutato _me_ a +capire quel che succede. Se vuoi +usarlo, com'@`e o modificato, sentiti libero di farlo (a condizione di +rispettare i vincoli posti da Davide, naturalmente, che credo siano stati +da me rispettati). + +Se dovessi includere questa spiegazione in una futura edizione, la inserirei +a una certa distanza dalla sezione 13.3.11, diciamo come una nota o come +un'appendice, in modo da non rivelare immediatamente la soluzione dell'enigma. + +Cordiali saluti, +-- +Chris Johansen {johansen at main dot nc dot us} + . . . collapsing the probability wave function, sending ripples of +certainty through the space-time continuum. + + +#! /usr/bin/gawk -f + +# Da "13.3.11 E ora per qualcosa di completamente differente" +# http://www.gnu.org/software/gawk/manual/html_node/Signature-Program.html#Signature-Program + +# Copyright © 2008 Davide Brini + +# Copying and distribution of the code published in this page, with +# or without modification, are permitted in any medium without +# royalty provided the copyright notice and this notice are preserved. + +BEGIN { + O = "~" ~ "~"; # 1 + o = "==" == "=="; # 1 + o += +o; # 2 + x = O "" O; # 11 + + + while ( X++ <= x + o + o ) c = c "%c"; + + # O vale 1 + # o vale 2 + # x vale 11 + # X vale 17 + # c vale "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c" + + printf c, + ( x - O )*( x - O), # 100 d + x*( x - o ) - o, # 97 a + x*( x - O ) + x - O - o, # 118 v + +x*( x - O ) - x + o, # 101 e + X*( o*o + O ) + x - O, # 95 _ + X*( X - x ) - o*o, # 98 b + ( x + X )*o*o + o, # 114 r + x*( X - x ) - O - O, # 64 @ + x - O + ( O + o + X + x )*( o + O ), # 103 g + X*X - X*( x - O ) - x + O, # 109 m + O + X*( o*( o + O ) + O ), # 120 x + +x + O + X*o, # 46 . + x*( x - o), # 99 c + ( o + X + x )*o*o - ( x - O - O ), # 111 0 + O + ( X - x )*( X + O ), # 109 m + x - O # 10 \n +} +@end ignore + +@node Sommario dei programmi +@section Sommario + +@itemize @value{BULLET} +@item +I programmi illustrati in questo @value{CHAPTER} +ripropongo la tesi secondo cui leggere programmi @`e una maniera eccellente +per imparare a fare della buona programmazione. + +@item +Usare @samp{#!} per rendere i programmi @command{awk} direttamente eseguibili +ne rende pi@`u semplice l'uso. In alternativa, si pu@`o invocare un +programma usando @samp{awk -f @dots{}}. + +@item +Reimplementare programmi POSIX standard in @command{awk} @`e un esercizio +piacevole; il potere espressivo di @command{awk} consente di scrivere tali +programmi usando relativamente poche righe di codice, nonostante i programmi +risultanti siano funzionalmente completi e utilizzabili. + +@item +Una delle debolezze della versione standard di @command{awk} riguarda il +lavorare con singoli caratteri. La possibilit@`a di usare @code{split()} con +la stringa nulla come separatore pu@`o semplificare considerevolmente tale +compito. + +@item +Gli esempi proposti dimostrano l'utilit@`a delle funzioni di libreria introdotte +@iftex +nel +@end iftex +@ifnottex +in +@end ifnottex +@ref{Funzioni di libreria} +per un numero (sia pur piccolo) di programmi reali. + +@item +Oltre a reinventare la ruota POSIX, altri programmi risolvono una serie di +problemi interessanti, come trovare delle parole duplicate in un testo, +stampare etichette per lettere, e trovare anagrammi. + +@end itemize + +@c EXCLUDE START +@node Esercizi sui programmi +@section Esercizi + +@enumerate +@item +Riscrivere @file{cut.awk} (@pxref{Programma cut}) +usando @code{split()} con @code{""} come separatore. + +@item +@iftex +Nella +@end iftex +@ifnottex +In +@end ifnottex +@ref{Programma egrep}, @`e detto che @samp{egrep -i} potrebbe essere +simulato in versioni di @command{awk} che non prevedono @code{IGNORECASE} +usando @code{tolower()} sulla riga e nei criteri di ricerca. In una nota a +pi@`e di pagina @`e anche detto che questa soluzione ha un problema: in output +viene scritta la riga tradotta (a lettere minuscole), e non quella originale. +Risolvere questo problema. +@c Exercise: Fix this, w/array and new line as key to original line + +@item +La versione POSIX di @command{id} accetta opzioni che controllano quali +informazioni stampare. Modificare la versione @command{awk} +(@pxref{Programma id}) per accettare gli stessi argomenti e funzionare allo +stesso modo. + +@item +Il programma @code{split.awk} (@pxref{Programma split}) presuppone che le +lettere siano contigue nella codifica dei caratteri, +il che non @`e vero per sistemi che usano la codifica EBCDIC. +Risolvere questo problema. +(Suggerimento: Considerare un modo diverso di analizzare l'alfabeto, +senza appoggiarsi sulle funzioni @code{ord()} e @code{chr()}.) + +@item +Nel programma @file{uniq.awk} (@pxref{Programma uniq}, la +logica per scegliere quali righe stampare rappresenta una +@dfn{macchina a stati}, +ossia ``un dispositivo che pu@`o essere in uno di un insieme di stati +stabili, a seconda dello stato in cui si trovava in precedenza, e del +valore corrente dei suoi +input.''@footnote{Questo @`e la definizione trovata usando +@code{define: state machine} come chiave di ricerca in Google.} +Brian Kernighan suggerisce che +``un approccio alternativo alle macchine a stati @`e di leggere tutto l'input +e metterlo in un vettore, e quindi usare gli indici. @`E quasi sempre pi@`u +semplice da programmare, e per la maggior parte degli input in cui si pu@`o +usare, altrettanto veloce in esecuzione.'' Riscrivere la logica del +programma seguendo questa indicazione. + + +@item +Perch@'e il programma @file{wc.awk} (@pxref{Programma wc}) non pu@`o +limitarsi a usare il valore di @code{FNR} nella funziona @code{a_fine_file()}? +Suggerimento: Esaminare il codice +@iftex +nella +@end iftex +@ifnottex +in +@end ifnottex +@ref{Funzione filetrans}. + +@ignore +@command{wc} can't just use the value of @code{FNR} in +@code{endfile()}. If you examine the code in @ref{Filetrans Function}, +you will see that @code{FNR} has already been reset by the time +@code{endfile()} is called. +@end ignore + +@item +La manipolazione di singoli caratteri nel programma @command{translate} +(@pxref{Programma translate}) @`e farraginosa usando le funzione standard +@command{awk}. Poich@'e @command{gawk} pu@`o dividere stringhe in caratteri +singoli usando come separatore @code{""}, come si potrebbe usare questa +funzionalit@`a per semplificare il programma? + +@item +Il programma @file{extract.awk} (@pxref{Programma extract}) @`e stato +scritto prima che @command{gawk} avesse a disposizione la funzione +@code{gensub()}. Usarla per semplificare il codice. + +@item +Si confronti la velocit@`a di esecuzione del programma @file{awksed.awk} +(@pxref{Programma sed semplice}) con il pi@`u diretto: + +@example +BEGIN @{ + stringa = ARGV[1] + rimpiazzo = ARGV[2] + ARGV[1] = ARGV[2] = "" +@} + +@{ gsub(stringa, rimpiazzo); print @} +@end example + +@item +Quali sono vantaggi e svantaggi di @file{awksed.awk} rispetto al vero +programma di utilit@`a @command{sed}? + +@ignore + Advantage: egrep regexps + speed (?) + Disadvantage: no & in replacement text + +Others? +@end ignore + +@item +@iftex +Nella +@end iftex +@ifnottex +In +@end ifnottex +@ref{Programma igawk}, si @`e detto che non tentando di salvare la riga +letta con @code{getline} nella funzione @code{percorso()}, mentre si +controlla l'accessibilit@`a del file da usare nel programma principale, +semplifica notevolmente le cose. Quale problema @`e peraltro generato cos@`{@dotless{i}} +facendo? +@c answer, reading from "-" o /dev/stdin + +@cindex percorso di ricerca per file sorgente +@cindex ricerca, percorso di, per file sorgente +@cindex file sorgente, percorso di ricerca per +@cindex directory, ricerca +@item +Come ulteriore esempio dell'idea che non sempre @`e necessario aggiungere +nuove funzionalit@`a a un programma, si consideri l'idea di avere due file in +una directory presente nel percorso di ricerca: + +@table @file +@item default.awk +Questo file contiene un insieme di funzioni di libreria di default, come +@code{getopt()} e @code{assert()}. + +@item sito.awk +Questo file contiene funzioni di libreria che sono specifiche di +un sito o di un'installazione; cio@`e, funzioni sviluppate localmente. +Mantenere due file separati consente a @file{default.awk} di essere +modificato in seguito a nuove versioni di @command{gawk}, senza che +l'amministratore di sistema debba ogni volta aggiornarlo aggiungendo le +funzioni locali. +@end table + +Un utente +@c Karl Berry, karl@ileaf.com, 10/95 +ha suggerito che @command{gawk} venga modificato per leggere automaticamente +questi file alla partenza. Piuttosto, sarebbe molto semplice +modificare @command{igawk} per farlo. Poich@'e @command{igawk} @`e capace di +elaborare direttive @code{@@include} +nidificate, @file{default.awk} potrebbe contenere semplicemente la lista di +direttive @code{@@include} con le funzioni di libreria desiderate. +Fare questa modifica. + +@item +Modificare @file{anagram.awk} (@pxref{Programma anagram}), per evitare di +usare il programma di utilit@`a esterno @command{sort}. + +@end enumerate +@c EXCLUDE END + +@ifnotinfo +@part @value{PART3}Andare oltre @command{awk} con @command{gawk} +@end ifnotinfo + +@ifdocbook +La Parte III riguarda funzionalit@`a proprie di @command{gawk}. +Contiene i seguenti capitoli: + +@itemize @value{BULLET} +@item +@ref{Funzionalit@`a avanzate} + +@item +@ref{Internazionalizzazione} + +@item +@ref{Debugger} + +@item +@ref{Calcolo con precisione arbitraria} + +@item +@ref{Estensioni dinamiche} +@end itemize +@end ifdocbook + +@node Funzionalit@`a avanzate +@chapter Funzionalit@`a avanzate di @command{gawk} +@cindex @command{gawk}, funzionalit@`a avanzate +@cindex avanzate, funzionalit@`a, di @command{gawk} +@ignore +Contributed by: Peter Langston <pud!psl@bellcore.bellcore.com> + + Found in Steve English's "signature" line: + +"Write documentation as if whoever reads it is a violent psychopath +who knows where you live." +@end ignore +@cindex Langston, Peter +@cindex English, Steve +@quotation +@i{Scrivete la documentazione supponendo che chiunque la legger@`a sia uno psicopatico +violento, che conosce il vostro indirizzo di casa.} +@author Steve English, citato da Peter Langston +@end quotation + +Questo @value{CHAPTER} tratta delle funzionalit@`a avanzate in @command{gawk}. +@`E un po' come un ``pacco sorpresa'' di argomenti che non sono collegati tra di +loro in altro modo. +Per prima cosa, vediamo un'opzione da riga di comando che consente a +@command{gawk} di riconoscere i numeri non-decimali nei dati in input, e non +soltanto nei programmi @command{awk}. +Poi vengono illustrate delle funzionalit@`a speciali di @command{gawk} per +l'ordinamento di vettori. Quindi viene trattato dettagliatamente l'I/O +bidirezionale, di cui si @`e fatto cenno in precedenti parti di questo +@value{DOCUMENT}, assieme ai fondamenti sulle reti TCP/IP. +Infine, vediamo come @command{gawk} +pu@`o tracciare il @dfn{profilo} di un programma @command{awk}, cos@`{@dotless{i}} che si +possa ritoccarlo per migliorarne le prestazioni. + +@c FULLXREF ON +Altre funzionalit@`a avanzate vengono trattate separatamente dedicando un +@value{CHAPTER} per ciascuna di esse: + +@itemize @value{BULLET} +@item +@iftex +Il +@end iftex +@ref{Internazionalizzazione}, parla di come internazionalizzare +i propri programmi @command{awk}, in modo che parlino pi@`u lingue +nazionali. + +@item +@iftex +Il +@end iftex +@ref{Debugger}, descrive il debugger dalla riga di comando disponibile +all'interno di +@command{gawk} per individuare errori nei programmi @command{awk}. + +@item +@iftex +Il +@end iftex +@ref{Calcolo con precisione arbitraria}, illustra come si pu@`o usare +@command{gawk} per eseguire calcoli con precisione arbitraria. + +@item +@iftex +Il +@end iftex +@ref{Estensioni dinamiche}, +tratta della capacit@`a di aggiungere dinamicamente nuove funzioni predefinite a +@command{gawk}. +@end itemize +@c FULLXREF OFF + +@menu +* Dati non decimali:: Consentire dati di input non decimali. +* Ordinamento di vettori:: Modi per controllare la visita di un vettore + e il suo ordinamento. +* I/O bidirezionale:: Comunicazione bidirezionale con un altro + processo. +* Reti TCP/IP:: Usare @command{gawk} per programmazione di rete. +* Profilare:: Profilare i propri programmi @command{awk}. +* Sommario funzionalit@`a avanzate:: Sommario delle funzionalit@`a avanzate. +@end menu + +@node Dati non decimali +@section Consentire dati di input non decimali +@cindex opzione @option{--non-decimal-data} +@c @cindex funzionalit@`a avanzate, dati di input non decimali +@cindex input, dati non decimali +@cindex costanti, non decimali + +Se si esegue @command{gawk} con l'opzione @option{--non-decimal-data}, +si possono avere valori in base diversa da dieci nei dati di input: + +@example +$ @kbd{echo 0123 123 0x123 |} +> @kbd{gawk --non-decimal-data '@{ printf "%d, %d, %d\n", $1, $2, $3 @}'} +@print{} 83, 123, 291 +@end example + +Affinch@'e questa funzionalit@`a sia disponibile, i programmi devono essere +scritti in modo che @command{gawk} tratti i dati come valori numerici: + +@example +$ @kbd{echo 0123 123 0x123 | gawk '@{ print $1, $2, $3 @}'} +@print{} 0123 123 0x123 +@end example + +@noindent +L'istruzione @code{print} tratta le sue espressioni come se fossero stringhe. +Sebbene i campi possano comportarsi come numeri, quando necessario, +essi rimangono sempre stringhe, per cui @code{print} non cerca di elaborarli +come se fossero numeri. Si deve aggiungere zero a un campo affich@'e venga +considerato come un numero. Per esempio: + +@example +$ @kbd{echo 0123 123 0x123 | gawk --non-decimal-data '} +> @kbd{@{ print $1, $2, $3} +> @kbd{print $1 + 0, $2 + 0, $3 + 0 @}'} +@print{} 0123 123 0x123 +@print{} 83 123 291 +@end example + +Poich@'e capita comunemente di avere dati di tipo decimale con degli zeri iniziali, +e poich@'e l'uso di questa funzionalit@`a pu@`o portare a risultati inattesi, il +comportamento di default @`e quello lasciarla disabilitata. Se si vuole, la si +deve richiedere esplicitamente. + +@cindex programmazione, convenzioni di, opzione @code{--non-decimal-data} +@cindex @option{--non-decimal-data}, opzione, funzione @code{strtonum()} e +@cindex @code{strtonum()}, funzione (@command{gawk}), opzione @code{--non-decimal-data} e +@quotation ATTENZIONE +@emph{L'uso di questa opzione non @`e consigliata.} +Pu@`o provocare errori molto seri eseguendo vecchi programmi. +Al suo posto @`e meglio usare la funzione @code{strtonum()} per convertire i dati +(@pxref{Funzioni per stringhe}). +Questo rende i programmi pi@`u facili da scrivere e pi@`u facili da leggere, e +porta a risultati meno inattesi. + +Quest'opzione potrebbe sparire dalle versioni future di @command{gawk}. +@end quotation + +@node Ordinamento di vettori +@section Controllare la visita di un vettore e il suo ordinamento + +@command{gawk} permette di controllare l'ordine con cui un ciclo +@samp{for (@var{indice} in @var{vettore})} +attraversa un vettore. + +Inoltre, due funzioni predefinite, @code{asort()} e @code{asorti()}, +permettono di mettere in ordine i vettori sulla base, rispettivamente, dei +valori e degli indici del vettore. Queste due funzioni danno anche il +controllo sui criteri in base ai quali riordinare gli elementi del vettore. + +@menu +* Controllare visita vettori:: Come usare PROCINFO["sorted_in"]. +* Funzioni di ordinamento di vettori:: Come usare @code{asort()} e @code{asorti()}. +@end menu + +@node Controllare visita vettori +@subsection Controllare visita vettori + +Per default, l'ordine secondo il quale un ciclo @samp{for (@var{indice} in +@var{vettore})} scorre un vettore non @`e definito; in genere si basa +sull'implementazione interna dei vettori all'interno di @command{awk}. + +Spesso, tuttavia, si vorrebbe poter eseguire un ciclo sugli elementi in un +determinato ordine scelto dall'utente programmatore. Con @command{gawk} +si pu@`o fare. + +@iftex +La +@end iftex +@ref{Controllare visita} parla di come si possono assegnare valori speciali +predefiniti a @code{PROCINFO["sorted_in"]} per controllare l'ordine secondo il +quale @command{gawk} attraversa un vettore +durante un ciclo @code{for}. + +Inoltre, il valore di @code{PROCINFO["sorted_in"]} pu@`o essere un nome di +funzione.@footnote{Questo @`e il motivo per cui gli ordinamenti predefiniti +iniziano con il carattere @samp{@@}, che non pu@`o essere usato in un +identificatore.} +Questo consente di scorrere un vettore sulla base di un qualsiasi criterio +personalizzato. Gli elementi del vettore vengono ordinati in accordo col valore +ritornato da questa funzione. La funzione che fa il confronto dovrebbe essere +definita con almeno quattro argomenti: + +@example +function confronta(i1, v1, i2, v2) +@{ + @var{confronta gli elementi 1 e 2 in qualche modo} + @var{return < 0; 0; o > 0} +@} +@end example + +Qui, @code{i1} e @code{i2} sono gli indici, e @code{v1} e @code{v2} +sono i corrispondenti valori dei due elementi che si stanno confrontando. +@code{v1} oppure @code{v2}, o entrambi, possono essere vettori se il vettore +che si sta visitando contiene sottovettori come valori. +(@xref{Vettori di vettori} per maggiori informazioni sui sottovettori.) +I tre possibili valori di ritorno sono interpretati nel seguente modo: + +@table @code +@item confronta(i1, v1, i2, v2) < 0 +L'indice @code{i1} viene prima dell'indice @code{i2} durante l'avanzamento +del ciclo. + +@item confronta(i1, v1, i2, v2) == 0 +Gli indici @code{i1} e @code{i2} +sono equivalenti, ma l'ordine tra loro non @`e definito. + +@item confronta(i1, v1, i2, v2) > 0 +L'indice @code{i1} viene dopo l'indice @code{i2} durante l'avanzamento del +ciclo. +@end table + +La prima funzione di confronto pu@`o essere usata per scorrere un vettore +secondo l'ordine numerico degli indici: + +@example +function cfr_ind_num(i1, v1, i2, v2) +@{ + # confronto di indici numerici, ordine crescente + return (i1 - i2) +@} +@end example + +La seconda funzione scorre un vettore secondo l'ordine delle stringhe +dei valori degli elementi piuttosto che secondo gli indici: + +@example +function cfr_val_str(i1, v1, i2, v2) +@{ + # confronto di valori di stringa, ordine crescente + v1 = v1 "" + v2 = v2 "" + if (v1 < v2) + return -1 + return (v1 != v2) +@} +@end example + +La terza funzione di confronto restituisce dapprima tutti i numeri, e dopo +questi le stringhe numeriche senza spazi iniziali o finali, durante +l'avanzamento del ciclo: + +@example +function cfr_val_num_str(i1, v1, i2, v2, n1, n2) +@{ + # confronto mettendo i numeri prima dei valori di stringa, + # ordine crescente + n1 = v1 + 0 + n2 = v2 + 0 + if (n1 == v1) + return (n2 == v2) ? (n1 - n2) : -1 + else if (n2 == v2) + return 1 + return (v1 < v2) ? -1 : (v1 != v2) +@} +@end example + +Qui vediamo un programma principale che mostra come @command{gawk} +si comporta usando ciascuna delle funzioni precedenti: + +@example +BEGIN @{ + data["uno"] = 10 + data["due"] = 20 + data[10] = "uno" + data[100] = 100 + data[20] = "due" + + f[1] = "cfr_ind_num" + f[2] = "cfr_val_str" + f[3] = "cfr_val_num_str" + for (i = 1; i <= 3; i++) @{ + printf("Funzione di ordinamento: %s\n", f[i]) + PROCINFO["sorted_in"] = f[i] + for (j in data) + printf("\tdata[%s] = %s\n", j, data[j]) + print "" + @} +@} +@end example + +I risultati dell'esecuzione del programma sono questi: + +@example +$ @kbd{gawk -f compdemo.awk} +@print{} Funzione di ordinamento: cfr_ind_num @ii{Ordinamento per indice numerico} +@print{} data[uno] = 10 +@print{} data[due] = 20 @ii{Entrambe le stringhe sono numericamente zero} +@print{} data[10] = uno +@print{} data[20] = due +@print{} data[100] = 100 +@print{} +@print{} Funzione di ordinamento: cfr_val_str @ii{Ordinamento per valore degli} +@print{} @ii{elementi come stringhe} +@print{} data[uno] = 10 +@print{} data[100] = 100 @ii{La stringa 100 @`e minore della stringa 20} +@print{} data[due] = 20 +@print{} data[20] = due +@print{} data[10] = uno +@print{} +@print{} Funzione di ordinamento: cfr_val_num_str @ii{Ordinamento con tutti i} +@print{} @ii{valori numerici prima di tutte le stringhe} +@print{} data[uno] = 10 +@print{} data[due] = 20 +@print{} data[100] = 100 +@print{} data[20] = due +@print{} data[10] = uno +@end example + +Si provi a ordinare gli elementi di un file delle password del sistema GNU/Linux +in base al nome d'accesso dell'utente. Il seguente programma ordina i record +secondo una specifica posizione del campo e pu@`o essere usato per questo scopo: + +@example +# passwd-sort.awk --- semplice programma per ordinare in base alla +# posizione del campo +# la posizione del campo @`e specificata dalla variabile globale POS + +function per_campo(i1, v1, i2, v2) +@{ + # confronto per valore, come stringa, e in ordine crescente + return v1[POS] < v2[POS] ? -1 : (v1[POS] != v2[POS]) +@} + +@{ + for (i = 1; i <= NF; i++) + a[NR][i] = $i +@} + +END @{ + PROCINFO["sorted_in"] = "per_campo" + if (POS < 1 || POS > NF) + POS = 1 + for (i in a) @{ + for (j = 1; j <= NF; j++) + printf("%s%c", a[i][j], j < NF ? ":" : "") + print "" + @} +@} +@end example + +Il primo campo di ogni elemento del file delle password @`e il nome d'accesso +dell'utente, e i campi sono separati tra loro da due punti. +Ogni record definisce un sottovettore, +con ogni campo come elemento nel sottovettore. +L'esecuzione del programma produce +il seguente output: + +@example +$ @kbd{gawk -v POS=1 -F: -f sort.awk /etc/passwd} +@print{} adm:x:3:4:adm:/var/adm:/sbin/nologin +@print{} apache:x:48:48:Apache:/var/www:/sbin/nologin +@print{} avahi:x:70:70:Avahi daemon:/:/sbin/nologin +@dots{} +@end example + +Il confronto normalmente dovrebbe restituire sempre lo stesso valore quando +vien dato come argomento un preciso paio di elementi del vettore. Se viene +restituito un risultato non coerente, l'ordine @`e indefinito. Questo +comportamento pu@`o essere sfruttato per introdurre un ordinamento casuale in +dati apparentemente ordinati: + +@example +function ordina_a_caso(i1, v1, i2, v2) +@{ + # ordine casuale (attenzione: potrebbe non finire mai!) + return (2 - 4 * rand()) +@} +@end example + +Come gi@`a accennato, l'ordine degli indici @`e arbitrario se due elementi +risultano uguali. Normalmente questo non @`e un problema, ma lasciare che +elementi di uguale valore compaiano in ordine arbitrario pu@`o essere un +problema, specialmente quando si confrontano valori di elementi di un elenco. +L'ordine parziale di elementi uguali pu@`o cambiare quando il vettore viene +visitato di nuovo, se nel vettore vengono aggiunti o rimossi elementi. Un modo +per superare l'ostacolo quando si confrontano elementi con valori uguali @`e +quello di includere gli indici nelle regole di confronto. Si noti che questo +potrebbe rendere meno efficiente l'attraversamento del ciclo, per cui si +consiglia di farlo solo se necessario. Le seguenti funzioni di confronto +impongono un ordine deterministico, e si basano sul fatto che gli indici +(di stringa) di due elementi non sono mai uguali: +@example +function per_numero(i1, v1, i2, v2) +@{ + # confronto di valori numerici (e indici), ordine decrescente + return (v1 != v2) ? (v2 - v1) : (i2 - i1) +@} + +function per_stringa(i1, v1, i2, v2) +@{ + # confronto di valori di stringa (e indici), ordine decrescente + v1 = v1 i1 + v2 = v2 i2 + return (v1 > v2) ? -1 : (v1 != v2) +@} +@end example + +@c Avoid using the term ``stable'' when describing the unpredictable behavior +@c if two items compare equal. Usually, the goal of a "stable algorithm" +@c is to maintain the original order of the items, which is a meaningless +@c concept for a list constructed from a hash. + +Una funzione di confronto personalizzata spesso pu@`o semplificare +l'attraversamento del +ciclo ordinato, e il solo limite @`e il cielo, quando si va a progettare +una funzione di questo tipo. + +Quando i confronti tra stringhe son fatti durante un'operazione di ordinamento, +per valori di elementi che, uno o entrambi, non sono numeri, o per +indici di elementi gestiti come stringhe, il valore di @code{IGNORECASE} +(@pxref{Variabili predefinite}) controlla se +i confronti trattano corrispondenti lettere maiuscole e minuscole +come equivalenti o come distinte. + +Un'altra cosa da tenere a mente @`e che nel caso di sottovettori, i valori degli +elementi possono essere a loro volta dei vettori; una funzione di confronto in +produzione dovrebbe usare la funzione @code{isarray()} +(@pxref{Funzioni per i tipi}) +per controllare ci@`o, e scegliere un ordinamento preciso per i sottovettori. + +Tutti gli ordinamenti basati su @code{PROCINFO["sorted_in"]} +sono disabilitati in modalit@`a POSIX, +perch@'e il vettore @code{PROCINFO} in questo caso non @`e speciale. + +Come nota a margine, si @`e visto che ordinare gli indici del vettore prima di +scorrere il vettore porta a un incremento variabile dal 15% al 20% del tempo di +esecuzione dei programmi @command{awk}. Per questo motivo l'attraversamento +ordinato di vettori non @`e il default. + +@c The @command{gawk} +@c maintainers believe that only the people who wish to use a +@c feature should have to pay for it. + +@node Funzioni di ordinamento di vettori +@subsection Ordinare valori e indici di un vettore con @command{gawk} + +@cindex vettori, ordinamento dei +@cindexgawkfunc{asort} +@cindex @code{asort()}, funzione (@command{gawk}), ordinamento di vettori +@cindex funzione @code{asort()} (@command{gawk}), ordinamento di vettori +@cindexgawkfunc{asorti} +@cindex @code{asorti()}, funzione (@command{gawk}), ordinamento di vettori +@cindex funzione @code{asorti()} (@command{gawk}), ordinamento di vettori +@cindex @code{sort()}, funzione, ordinamento di vettori +@cindex funzione @code{sort()}, ordinamento di vettori +Nella maggior parte delle implementazioni di @command{awk}, ordinare un vettore +richiede una funzione @code{sort()}. Questo pu@`o essere istruttivo per provare +diversi algoritmi di ordinamento, ma normalmente non @`e questo lo scopo del +programma. In @command{gawk} ci sono le funzioni predefinite @code{asort()} e +@code{asorti()} (@pxref{Funzioni per stringhe}) per i vettori ordinati. +Per esempio: + +@example +@var{riempire il vettore} dati +n = asort(dati) +for (i = 1; i <= n; i++) + @var{fare qualcosa con} dati[i] +@end example + +Dopo la chiamata ad @code{asort()}, il vettore @code{dati} @`e indicizzato da 1 +a @var{n}, il numero totale di elementi in @code{dati}. +(Questo conteggio @`e il valore di ritorno di @code{asort()}). +@code{dati[1]} @value{LEQ} @code{dati[2]} @value{LEQ} @code{dati[3]}, e cos@`{@dotless{i}} +via. Il confronto di default @`e basato sul tipo di elementi +(@pxref{Tipi di variabile e confronti}). +Tutti i valori numerici vengono prima dei valori di stringa, +che a loro volta vengono prima di tutti i sottovettori. + +@cindex effetti collaterali, funzione @code{asort()} +@cindex funzione @code{asort()}, effetti collaterali +Un effetto collaterale rilevante nel chiamare @code{asort()} @`e che +@emph{gli indici originali del vettore vengono persi irreparabilmente}. +Poich@'e questo non sempre @`e opportuno, @code{asort()} accetta un +secondo argomento: + +@example +@var{populate the array} orig +n = asort(orig, dest) +for (i = 1; i <= n; i++) + @var{fai qualcosaa con} dest[i] +@end example + +In questo caso, @command{gawk} copia il vettore @code{orig} nel vettore +@code{dest} e ordina @code{dest}, distruggendo i suoi indici. +Tuttavia il vettore @code{orig} non viene modificato. + +Spesso, ci@`o di cui si ha bisogno @`e di ordinare per i valori degli +@emph{indici} invece che per i valori degli elementi. Per far questo si usa la +funzione @code{asorti()}. L'interfaccia e il comportamento sono identici a +quelli di @code{asort()}, solo che per l'ordinamento vengono usati i valori +degli indici, che diventano i valori del vettore risultato: + +@example +@{ orig[$0] = una_funz($0) @} + +END @{ + n = asorti(orig, dest) + for (i = 1; i <= n; i++) @{ + @ii{Lavora direttamente con gli indici ordinati:} + @var{fa qualcosa con} dest[i] + @dots{} + @ii{Accede al vettore originale attraverso gli indici ordinati:} + @var{fa qualcosa con} orig[dest[i]] + @} +@} +@end example + +Fin qui, tutto bene. Ora inizia la parte interessante. Sia @code{asort()} +che @code{asorti()} accettano un terzo argomento di stringa per controllare il +confronto di elementi del vettore. Quando abbiamo introdotto @code{asort()} e +@code{asorti()} nella @ref{Funzioni per stringhe}, abbiamo ignorato questo terzo +argomento; comunque, @`e giunto il momento di descrivere come questo argomento +influenza queste due funzioni. + +Fondamentalmente, il terzo argomento specifica come dev'essere ordinato il +vettore. Ci sono due possibilit@`a. Come per @code{PROCINFO["sorted_in"]}, +quest'argomento pu@`o essere uno degli argomenti predefiniti che @command{gawk} +fornisce (@pxref{Controllare visita}), o pu@`o essere il nome di una funzione +definita dall'utente (@pxref{Controllare visita vettori}). + +Nell'ultimo caso, @emph{la funzione pu@`o confrontare gli elementi in qualunque +modo si voglia}, prendendo in considerazione solo gli indici, solo i valori, +o entrambi. Questo @`e estremamente potente. + +Una volta che il vettore @`e ordinato, @code{asort()} prende i @emph{valori} nel +loro ordine finale e li usa per riempire il vettore risultato, mentre +@code{asorti()} prende gli @emph{indici} nel loro ordine finale e li usa per +riempire il vettore risultato. + +@cindex conteggio riferimenti, ordinamento vettori +@quotation NOTA +Copiare indici ed elementi non @`e dispendioso in termini di memoria. +Internamente, @command{gawk} mantiene un @dfn{conteggio dei riferimenti} ai +dati. Per esempio, dopo che @code{asort()} copia il primo vettore nel +secondo, in memoria c'@`e ancora una sola copia dei dati degli elementi +del vettore originale, ed entrambi i vettori accedono all'unica copia di +valori che esiste in memoria. +@end quotation + +@c Document It And Call It A Feature. Sigh. +@cindex @command{gawk}, variabile @code{IGNORECASE} in +@cindex vettori, ordinamento, variabile @code{IGNORECASE} e +@cindex @code{IGNORECASE}, variabile, e funzioni di ordinamento dei vettori +@cindex variabile @code{IGNORECASE}, e funzioni di ordinamento dei vettori +Poich@'e @code{IGNORECASE} influenza i confronti tra stringhe, il valore di +@code{IGNORECASE} influisce anche sull'ordinamento sia con @code{asort()} che +con @code{asorti()}. +Si noti inoltre che l'ordinamento della localizzazione @emph{non} entra in +gioco; i confronti sono basati solamente sul valore dei +caratteri.@footnote{Ci@`o @`e vero perch@'e il confronto basato sulla localizzazione +avviene solo quando si @`e in modalit@`a POSIX-compatibile, e poich@'e @code{asort()} +e @code{asorti()} sono estensioni di @command{gawk}, esse non sono disponibili +in quel caso.} + +L'esempio seguente mostra l'uso di una funzione di confronto usata con +@code{asort()}. La funzione di confronto, @code{confronta_in_minuscolo()}, +trasforma gli elementi da confrontare in lettere minuscole, in modo da avere +confronti che non dipendono da maiuscolo/minuscolo. + +@example +# confronta_in_minuscolo --- confronta stringhe ignorando maiuscolo/minuscolo + +function confronta_in_minuscolo(i1, v1, i2, v2, l, r) +@{ + l = tolower(v1) + r = tolower(v2) + + if (l < r) + return -1 + else if (l == r) + return 0 + else + return 1 +@} +@end example + +E questo programma pu@`o essere usato per provarla: + +@example +# programma di test + +BEGIN @{ + Letters = "abcdefghijklmnopqrstuvwxyz" \ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + split(Letters, data, "") + + asort(data, risultato, "confronta_in_minuscolo") + + j = length(risultato) # numero elementi del vettore "risultato" + for (i = 1; i <= j; i++) @{ + printf("%s", risultato[i]) + if (i % (j/2) == 0) + # a met@`a, la stampa del vettore va a capo + printf("\n") + else + printf(" ") + @} +@} +@end example + +Se si esegue il programma, si ottiene: + +@example +$ @kbd{gawk -f confronta_in_minuscolo.awk} +@print{} A a B b c C D d e E F f g G H h i I J j k K l L M m +@print{} n N O o p P Q q r R S s t T u U V v w W X x y Y z Z +@end example + +@node I/O bidirezionale +@section Comunicazioni bidirezionali con un altro processo + +@c 8/2014. Neither Mike nor BWK saw this as relevant. Commenting it out. +@ignore +@cindex Brennan, Michael +@cindex programmers, attractiveness of +@smallexample +@c Path: cssun.mathcs.emory.edu!gatech!newsxfer3.itd.umich.edu!news-peer.sprintlink.net!news-sea-19.sprintlink.net!news-in-west.sprintlink.net!news.sprintlink.net!Sprint!204.94.52.5!news.whidbey.com!brennan +From: brennan@@whidbey.com (Mike Brennan) +Newsgroups: comp.lang.awk +Subject: Re: Learn the SECRET to Attract Women Easily +Date: 4 Aug 1997 17:34:46 GMT +@c Organization: WhidbeyNet +@c Lines: 12 +Message-ID: <5s53rm$eca@@news.whidbey.com> +@c References: <5s20dn$2e1@chronicle.concentric.net> +@c Reply-To: brennan@whidbey.com +@c NNTP-Posting-Host: asn202.whidbey.com +@c X-Newsreader: slrn (0.9.4.1 UNIX) +@c Xref: cssun.mathcs.emory.edu comp.lang.awk:5403 + +On 3 Aug 1997 13:17:43 GMT, Want More Dates??? +<tracy78@@kilgrona.com> wrote: +>Learn the SECRET to Attract Women Easily +> +>The SCENT(tm) Pheromone Sex Attractant For Men to Attract Women + +The scent of awk programmers is a lot more attractive to women than +the scent of perl programmers. +-- +Mike Brennan +@c brennan@@whidbey.com +@end smallexample +@end ignore + +@cindex funzionalit@`a avanzate, processi@comma{} comunicare con +@cindex processi, comunicazioni bidirezionali con +Spesso @`e utile poter +inviare dati a un programma separato che +li elabori e in seguito leggere il risultato. Questo pu@`o essere sempre +fatto con file temporanei: + +@example +# Scrivere i dati per l'elaborazione +filetemp = ("mieidati." PROCINFO["pid"]) +while (@var{non dipendente dai dati}) + print @var{dati} | ("sottoprogramma > " filetemp) +close("sottoprogramma > " filetemp) + +# Legge il risultato, rimuove filetemp quando ha finito +while ((getline nuovidati < filetemp) > 0) + @var{elabora} nuovidati @var{secondo le esigenze} +close(filetemp) +system("rm " filetemp) +@end example + +@noindent +Questo funziona, ma non @`e elegante. Tra le altre cose, richiede che il +programma venga eseguito in una directory che non pu@`o essere condivisa tra gli +utenti; per esempio, @file{/tmp} non pu@`o esserlo, poich@'e potrebbe accadere che +un altro utente stia usando un file temporaneo con lo stesso +nome.@footnote{Michael Brennan suggerisce l'uso di @command{rand()} per +generare @value{FNS} unici. Questo @`e un punto valido; tuttavia, i file +temporanei rimangono pi@`u difficili da usare delle @dfn{pipe} bidirezionali.} @c 8/2014 + +@cindex coprocessi +@cindex input/output bidirezionale +@cindex @code{|} (barra verticale), operatore @code{|&} (I/O) +@cindex barra verticale (@code{|}), operatore @code{|&} (I/O) +@cindex @command{csh}, comando, operatore @code{|&}, confronto con +@cindex comando @command{csh}, operatore @code{|&}, confronto con +Comunque, con @command{gawk}, @`e possibile aprire una @dfn{pipe} +@emph{bidirezionale} +verso un altro processo. Il secondo processo @`e chiamato @dfn{coprocesso}, +poich@'e viene eseguito in parallelo con @command{gawk}. La connessione +bidirezionale viene creata usando l'operatore @samp{|&} (preso in prestito +dalla shell Korn, @command{ksh}):@footnote{Questo @`e molto diverso dallo stesso +operatore nella C shell e in Bash.} + +@example +do @{ + print @var{dati} |& "sottoprogramma" + "sottoprogramma" |& getline risultato +@} while (@var{ci sono ancora dati da elaborare}) +close("sottoprogramma") +@end example + +La prima volta che viene eseguita un'operazione I/O usando l'operatore +@samp{|&}, +@command{gawk} crea una @dfn{pipeline} bidirezionale verso un processo figlio +che esegue l'altro programma. L'output creato con @code{print} o con +@code{printf} viene scritto nello standard input del programma, e il contenuto +dello standard output del programma pu@`o essere letto dal programma +@command{gawk} usando @code{getline}. +Come accade coi processi avviati con @samp{|}, il sottoprogramma pu@`o +essere un qualsiasi programma, o una @dfn{pipeline} di programmi, che pu@`o essere +avviato dalla shell. + +Ci sono alcune avvertenze da tenere presenti: + +@itemize @value{BULLET} +@item +Per come funziona internamente @command{gawk}, lo standard error +dei coprocessi va nello stesso posto dove va lo standard error del +genitore @command{gawk}. Non @`e possibile leggere lo standard error del +figlio separatamente. + +@cindex stalli +@cindex abbracci mortali +@cindex @dfn{deadlocks}, vedi stalli +@cindex bufferizzazione, dell'input/output +@cindex input/output, bufferizzazione +@cindex @code{getline}, comando, stalli e +@item +La permanenza in memoria (bufferizzazione) dell'I/O del sottoprocesso potrebbe +essere un problema. @command{gawk} automaticamente scrive su disco tutto +l'output spedito tramite la @dfn{pipe} al coprocesso. +Tuttavia, se il coprocesso non scrive su disco il suo output, +@command{gawk} potrebbe bloccarsi mentre esegue una @code{getline} per leggere +il risultato del coprocesso. Questo pu@`o portare a una situazione +conosciuta come @dfn{stallo} (@dfn{deadlock}, abbraccio mortale), in cui ciascun +processo rimane in attesa +che l'altro processo faccia qualcosa. +@end itemize + +@cindex @code{close()}, funzione, @dfn{pipe} bidirezionali e +@cindex funzione @code{close()}, @dfn{pipe} bidirezionali e +@`E possibile chiudere una @dfn{pipe} bidirezionale con un coprocesso solo in una +direzione, fornendo un secondo argomento, @code{"to"} o @code{"from"}, alla +funzione @code{close()} (@pxref{Chiusura file e @dfn{pipe}}). +Queste stringhe dicono a @command{gawk} di chiudere la @dfn{pipe}, rispettivamente +nella direzione che invia i dati al coprocesso e nella direzione che legge da +esso. + +@cindex @command{sort}, programma di utilit@`a, coprocessi e +@cindex programma di utilit@`a @command{sort}, coprocessi e +Questo @`e particolarmente necessario per usare il programma di utilit@`a +di sistema @command{sort} come parte di un coprocesso; +@command{sort} deve leggere @emph{tutti} i dati di input +prima di poter produrre un qualsiasi output. +Il programma @command{sort} non riceve un'indicazione di fine-file +(end-of-file) finch@'e @command{gawk} non chiude l'estremit@`a in scrittura della +@dfn{pipe}. + +Una volta terminata la scrittura dei dati sul programma @command{sort}, +si pu@`o chiudere il lato @code{"to"} della @dfn{pipe}, e quindi iniziare a leggere +i dati ordinati via @code{getline}. +Per esempio: + +@example +BEGIN @{ + comando = "LC_ALL=C sort" + n = split("abcdefghijklmnopqrstuvwxyz", a, "") + + for (i = n; i > 0; i--) + print a[i] |& comando + close(comando, "to") + + while ((comando |& getline line) > 0) + print "ricevuto", line + close(comando) +@} +@end example + +Questo programma scrive le lettere dell'alfabeto in ordine inverso, uno per +riga, attraverso la @dfn{pipe} bidirezionale verso @command{sort}. Poi chiude la +direzione di scrittura della @dfn{pipe}, in modo che @command{sort} riceva +un'indicazione di fine-file. Questo fa in modo che @command{sort} ordini i +dati e scriva i dati ordinati nel programma @command{gawk}. Una volta che +tutti i dati sono stati letti, @command{gawk} termina il coprocesso ed esce. + +Come nota a margine, l'assegnamento @samp{LC_ALL=C} nel comando @command{sort} +assicura che @command{sort} usi l'ordinamento tradizionale di Unix (ASCII). +Ci@`o non @`e strettamente necessario in questo caso, ma @`e bene sapere come farlo. + +Occorre prestare attenzione quando si chiude il lato @code{"from"} di una +@dfn{pipe} bidirezionale; in tal caso @command{gawk} attende che il +processo-figlio termini, il che pu@`o causare lo stallo del programma +@command{awk} in esecuzione. (Per questo motivo, questa particolare +funzionalit@`a @`e molto meno usata, in pratica, di quella che consente la +possibilit@`a di chiudere il lato @code{"to"} della @dfn{pipe}.) + +@quotation ATTENZIONE +Normalmente, +@`e un errore fatale (che fa terminare il programma @command{awk}) +scrivere verso il lato @code{"to"} di una @dfn{pipe} bidirezionale che +@`e stata chiusa, e lo stesso vale se si legge dal lato @code{"from"} +di una @dfn{pipe} bidirezionale che sia stata chiusa. + +@`E possibile impostare @code{PROCINFO["@var{comando}", "NONFATAL"]} +per far s@`{@dotless{i}} che tali operazioni non provochino la fine del programma +@command{awk}. Se lo si fa, @`e necessario controllare il valore +di @code{ERRNO} dopo ogni istruzione @code{print}, @code{printf}, +o @code{getline}. +@xref{Continuazione dopo errori} per ulteriori informazioni. +@end quotation + +@cindex @command{gawk}, vettore @code{PROCINFO} in +@cindex @code{PROCINFO}, vettore, e comunicazioni attraverso le @dfn{pty} +Per le comunicazioni bidirezionali si possono anche usare delle pseudo @dfn{tty} +(@dfn{pty}) al posto delle @dfn{pipe}, se il sistema in uso le prevede. +Questo vien fatto, a seconda del comando da usare, impostando un elemento +speciale nel vettore @code{PROCINFO} +(@pxref{Variabili auto-assegnate}), +in questo modo: + +@example +comando = "sort -nr" # comando, salvato in una variabile +PROCINFO[comando, "pty"] = 1 # aggiorna PROCINFO +print @dots{} |& comando # avvia la @dfn{pipe} bidirezionale +@dots{} +@end example + +@noindent +Se il sistema in uso non ha le @dfn{pty}, o se tutte le @dfn{pty} del sistema +sono in uso, @command{gawk} automaticamente torna a usare le @dfn{pipe} +regolari. + +Usare le @dfn{pty} in genere evita i problemi di stallo del buffer descritti +precedentemente, in cambio di un piccolo calo di prestazioni. Ci@`o dipende +dal fatto che la gestione delle @dfn{tty} @`e fatta una riga per volta. +Su sistemi che hanno il comando @command{stdbuf} (parte del pacchetto +@uref{http://www.gnu.org/software/coreutils/coreutils.html, +GNU Coreutils}), si pu@`o usare tale programma, invece delle @dfn{pty}. + +Si noti anche che le @dfn{pty} non sono completamente trasparenti. +Alcuni codici di controllo binari, come @kbd{Ctrl-d} per indicare la +condizione di file-file, sono interpetati dal gestore di @dfn{tty} +e non sono passati all'applicazione. + +@quotation ATTENZIONE +In ultima analisi, i coprocessi danno adito alla possibilit@`a di uno +@dfn{stallo} (deadlock) tra @command{gawk} e il programma in esecuzione +nel coprocesso. Ci@`o pu@`o succedere se si inviano ``troppi'' dati al +coprocesso, prima di leggere dati inviati dallo stesso; entrambi i +processi sono bloccati sulla scrittura dei dati, e nessuno dei due +@`e disponibile a leggere quelli che sono gi@`a stati scritti dall'altro. +Non c'@`e modo di evitare completamente una tale situazione; occorre una +programmazione attenta, insieme alla conoscenza del comportamento del +coprocesso. +@end quotation + +@node Reti TCP/IP +@section Usare @command{gawk} per la programmazione di rete +@cindex funzionalit@`a avanzate, programmazione di rete +@cindex avanzate, funzionalit@`a, programmazione di rete +@cindex reti, programmazione di +@cindex TCP/IP +@cindex @code{/inet/@dots{}}, file speciali (in @command{gawk}) +@cindex file speciali @code{/inet/@dots{}} (in @command{gawk}) +@cindex @code{/inet4/@dots{}}, file speciali (in @command{gawk}) +@cindex file speciali @code{/inet4/@dots{}} (in @command{gawk}) +@cindex @code{/inet6/@dots{}}, file speciali (in @command{gawk}) +@cindex file speciali @code{/inet6/@dots{}} (in @command{gawk}) +@cindex @code{EMRED} +@ifnotdocbook +@quotation +@code{EMRED}:@* +@ @ @ @ @i{A host is a host from coast to coast,@* +@ @ @ @ and nobody talks to a host that's close,@* +@ @ @ @ unless the host that isn't close@* +@ @ @ @ is busy, hung, or dead.} + +@code{EMRED}:@* +@ @ @ @ @i{Un computer @`e un computer lontano o vicino,@* +@ @ @ @ e nessuno parla con un computer vicino,@* +@ @ @ @ a meno che il computer lontano@* +@ @ @ @ sia occupato, fuori linea, o spento.} +@author Mike O'Brien (noto anche come Mr.@: Protocol) +@end quotation +@end ifnotdocbook + +@docbook +<blockquote> +<attribution>Mike O'Brien (aka Mr. Protocol)</attribution> +<literallayout class="normal"><literal>EMRED</literal>: + <emphasis>A host is a host from coast to coast,</emphasis> + <emphasis>and no-one can talk to host that's close,</emphasis> + <emphasis>unless the host that isn't close</emphasis> + <emphasis>is busy, hung, or dead.</emphasis></literallayout> +</blockquote> +@end docbook + +Oltre a poter aprire una @dfn{pipeline} bidirezionale verso un coprocesso +sullo stesso sistema +(@pxref{I/O bidirezionale}), +@`e possibile attivare una connessione bidirezionale verso un altro processo +o verso un altro sistema attraverso una connessione di rete IP. + +Si pu@`o pensare a questo semplicemente come a una @dfn{pipeline} bidirezionale +@emph{molto lunga} verso un coprocesso. +Il modo in cui @command{gawk} stabilisce quando usare una rete TCP/IP @`e +mediante il riconoscimento di speciali @value{FNS} che iniziano con +@samp{/inet/}, con @samp{/inet4/} o con @samp{/inet6/}. + +La sintassi completa del @value{FN} speciale @`e +@file{/@var{tipo-rete}/@var{protocollo}/@var{porta-locale}/@var{host-remoto}/@var{porta-remota}}. +I componenti sono: + +@table @var +@item tipo-rete +Specifica il tipo di connessione a internet da stabilire. +Si usa @samp{/inet4/} per usare solo IPv4, e +@samp{/inet6/} per usare solo IPv6. +Il semplice @samp{/inet/} (che usualmente @`e l'unica opzione) usa +il tipo di default del sistema, quasi certamente IPv4. + +@item protocollo +Il protocollo da usare sull'IP. Questo dev'essere o @samp{tcp} o +@samp{udp}, per una connessione IP rispettivamente TCP o UDP. +TCP dovrebbe venir usato per la maggior parte delle applicazioni. + +@item porta-locale +@cindex @code{getaddrinfo()}, funzione (libreria C) +@cindex funzione @code{getaddrinfo()} (libreria C) +Il numero di porta TCP o UDP da usare. Si usa un numero di porta di valore +@samp{0} quando si vuole che sia il sistema a scegliere una porta. +Questo @`e quel che si dovrebbe fare quando si scrive un'applicazione +cliente TCP o UDP. +Si pu@`o usare anche un nome di un servizio noto, come @samp{smtp} +o @samp{http}, nel qual caso @command{gawk} tenta di determinare +il numero di porta predefinito usando la funzione C @code{getaddrinfo()}. + +@item host-remoto +L'indirizzo IP o il nome di dominio completamente qualificato dell'host +internet al quale ci si vuol connettere. + +@item porta-remota +Il numero di porta TCP o UDP da usare sul particolare @var{host remoto}. +Anche in questo caso, si usi @samp{0} se non ci sono preferenze, +o alternativamente, un nome di servizio comunemente noto. +@end table + +@cindex @command{gawk}, variabile @code{ERRNO} in +@cindex @code{ERRNO}, variabile +@cindex variabile @code{ERRNO} +@quotation NOTA +Un insuccesso nell'apertura di un socket bidirezionale dar@`a luogo alla +segnalazione di un errore non fatale al codice chiamante. +Il valore di @code{ERRNO} indica l'errore (@pxref{Variabili auto-assegnate}). +@end quotation + +Si consideri il seguente esempio molto semplice: + +@example +BEGIN @{ + Servizio = "/inet/tcp/0/localhost/daytime" + Servizio |& getline + print $0 + close(Servizio) +@} +@end example + +Questo programma legge la data e l'ora corrente dal server @code{daytime} +TCP del sistema locale. +Stampa poi il risultato e chiude la connessione. + +Poich@'e questo tema @`e molto ampio, l'uso di @command{gawk} per +la programmazione TCP/IP viene documentato separatamente. +@ifinfo +Si veda +@inforef{Top, , General Introduction, gawkinet, @value{GAWKINETTITLE}}, +@end ifinfo +@ifnotinfo +Si veda +@uref{http://www.gnu.org/software/gawk/manual/gawkinet/, +@cite{@value{GAWKINETTITLE}}}, +che fa parte della distribuzione @command{gawk}, +@end ifnotinfo +per una introduzione e trattazione molto pi@`u completa e con molti +esempi. + +@quotation NOTA +@command{gawk} pu@`o aprire solo socket diretti. Al momento non c'@`e alcun modo +per accedere ai servizi disponibili su Secure Socket Layer +(SSL); questo comprende qualsiasi servizio web il cui URL inizia con +@samp{https://}. +@end quotation + + +@node Profilare +@section Profilare i propri programmi @command{awk} +@cindex @command{awk}, programmi, profilare +@cindex profilare programmi @command{awk} +@cindex @code{awkprof.out}, file +@cindex file @code{awkprof.out} + +@`E possibile tener traccia dell'esecuzione dei propri programmi @command{awk}. +Ci@`o si pu@`o fare passando l'opzione @option{--profile} a @command{gawk}. +Al termine dell'esecuzione, @command{gawk} crea un profilo del programma in un +file chiamato @file{awkprof.out}. A causa dell'attivit@`a di profilazione +l'esecuzione del programma @`e pi@`u lenta fino al 45% rispetto al normale. + +@cindex @option{--profile}, opzione +@cindex opzione @option{--profile} +Come mostrato nel seguente esempio, +l'opzione @option{--profile} pu@`o essere usata per cambiare il nome del file +su cui @command{gawk} scriver@`a il profilo: + +@example +gawk --profile=mioprog.prof -f mioprog.awk dati1 dati2 +@end example + +@noindent +Nell'esempio precedente, @command{gawk} mette il profilo in +@file{mioprog.prof} anzich@'e in @file{awkprof.out}. + +Vediamo ora una sessione d'esempio che mostra un semplice programma +@command{awk}, i suoi dati in input, e il risultato dell'esecuzione di +@command{gawk} con l'opzione @option{--profile}. Innanzitutto, il +programma @command{awk}: + +@example +BEGIN @{ print "Prima regola BEGIN" @} + +END @{ print "Prima regola END" @} + +/pippo/ @{ + print "trovato /pippo/, perbacco" + for (i = 1; i <= 3; i++) + sing() +@} + +@{ + if (/pippo/) + print "l'if @`e vero" + else + print "l'else @`e vero" +@} + +BEGIN @{ print "Seconda regola BEGIN" @} + +END @{ print "Seconda regola END" @} + +function sing( ignora) +@{ + print "Devo essere io!" +@} +@end example + +Questi sono i dati in input: + +@example +pippo +pluto +paperino +pippo +cianfrusaglie +@end example + +E questo @`e il file @file{awkprof.out} che @`e il risultato dell'esecuzione +del profilatore di @command{gawk} su questo programma e sui dati (quest'esempio +dimostra anche che i programmatori di @command{awk} a volte si alzano molto +presto al mattino per lavorare): + +@cindex @code{BEGIN}, criterio di ricerca, e profilatura +@cindex criterio di ricerca @code{BEGIN}, e profilatura +@cindex @code{END}, criterio di ricerca, e profilatura +@cindex criterio di ricerca @code{END}, e profilatura +@example + # profilo gawk, creato Mon Sep 29 05:16:21 2014 + + # BEGIN regola(e) + + BEGIN @{ + 1 print "Prima regola BEGIN" + @} + + BEGIN @{ + 1 print "Seconda regola BEGIN" + @} + + # Regola(e) + + 5 /pippo/ @{ # 2 + 2 print "trovato /pippo/, perbacco" + 6 for (i = 1; i <= 3; i++) @{ + 6 sing() + @} + @} + + 5 @{ + 5 if (/pippo/) @{ # 2 + 2 print "l'if @`e vero" + 3 @} else @{ + 3 print "l'else @`e vero" + @} + @} + + # END regola(e) + + END @{ + 1 print "Prima regola END" + @} + + END @{ + 1 print "Seconda regola END" + @} + + + # Funzioni, in ordine alfabetico + + 6 function sing(ignora) + @{ + 6 print "Devo essere io!" + @} +@end example + +Quest'esempio illustra molte caratteristiche fondamentali dell'output +della profilazione. +Queste sono: + +@itemize @value{BULLET} +@item +Il programma viene stampato nell'ordine: regole @code{BEGIN}, +regole @code{BEGINFILE}, +regole criterio di ricerca--azione, +regole @code{ENDFILE}, regole @code{END}, e funzioni, elencate +in ordine alfabetico. +Le regole @code{BEGIN} ed @code{END} multiple conservano le loro +distinte identit@`a, cos@`{@dotless{i}} come le regole @code{BEGINFILE} ed @code{ENDFILE} +multiple. + +@cindex criteri di ricerca, conteggi, in un profilo +@item +Le regole criterio di ricerca--azione hanno due conteggi. +Il primo conteggio, a sinistra della regola, mostra quante volte +il criterio di ricerca della regola @`e stato @emph{testato}. +Il secondo conteggio, alla destra della parentesi graffa aperta, +all'interno di un commento, +mostra quante volte l'azione della regola @`e stata @emph{eseguita}. +La differenza tra i due indica quante volte il criterio di ricerca della regola +@`e stato valutato come falso. + +@item +Analogamente, +il conteggio per un'istruzione @code{if}-@code{else} mostra quante volte +la condizione @`e stata testata. +Alla destra della parentesi graffa sinistra aperta per il corpo di @code{if} +c'@`e un conteggio che mostra quante volte la condizione @`e stata trovata vera. +Il conteggio per @code{else} indica +quante volte la verifica non ha avuto successo. + +@cindex cicli, conteggi per l'intestazione, in un profilo +@item +Il conteggio per un ciclo (come @code{for} +o @code{while}) mostra quante volte il test del ciclo @`e stato eseguito. +(Per questo motivo, non si pu@`o solamente guardare il conteggio sulla prima +istruzione in una regola per determinare quante volte la regola @`e stata +eseguita. Se la prima istruzione @`e un ciclo, il conteggio @`e ingannevole.) + +@cindex funzioni definite dall'utente, conteggi, in un profilo +@cindex definite dall'utente, funzioni, conteggi, in un profilo +@item +Per le funzioni definite dall'utente, il conteggio vicino alla parola chiave +@code{function} indica quante volte la funzione @`e stata chiamata. +I conteggi vicino alle istruzioni nel corpo mostrano quante volte +quelle istruzioni sono state eseguite. + +@cindex @code{@{@}} (parentesi graffe) +@cindex parentesi graffe (@code{@{@}}) +@item +L'impaginazione usa lo stile ``K&R'' con le tabulazioni. +Le parentesi graffe sono usate dappertutto, anche dove il corpo di un +@code{if}, di un @code{else} o di un ciclo @`e formato da un'unica istruzione. + +@cindex @code{()} (parentesi), in un profilo +@cindex parentesi (@code{()}), in un profilo +@item +Le parentesi vengono usate solo dov'@`e necessario, come si rileva dalla +struttura del programma e dalle regole di precedenza. +Per esempio, @samp{(3 + 5) * 4} significa sommare tre e cinque, quindi +moltiplicare il totale per quattro. Di contro, @samp{3 + 5 * 4} non ha +parentesi, e significa @samp{3 + (5 * 4)}. + +@ignore +@item +All string concatenations are parenthesized too. +(This could be made a bit smarter.) +@end ignore + +@item +Le parentesi vengono usate attorno agli argomenti di @code{print} +e @code{printf} solo quando l'istruzione +@code{print} o @code{printf} @`e seguita da una ridirezione. +Similarmente, se +l'oggetto di una ridirezione non @`e uno scalare, viene messo tra parentesi. + +@item +@command{gawk} mette dei commenti iniziali +davanti alle regole @code{BEGIN} ed @code{END}, +alle regole @code{BEGINFILE} ed @code{ENDFILE}, +alle regole criterio_di_ricerca--azione e alle funzioni. + +@end itemize + +La versione profilata del proprio programma potrebbe non apparire esattamente +come quella scritta durante la stesura del programma. Questo perch@'e +@command{gawk} crea la versione profilata facendo una ``stampa elegante'' della +sua rappresentazione interna del programma. Un vantaggio di ci@`o @`e che +@command{gawk} pu@`o produrre una rappresentazione standard. +Inoltre, cose come: + +@example +/pippo/ +@end example + +@noindent +appaiono come: + +@example +/pippo/ @{ + print $0 +@} +@end example + +@noindent +che @`e corretto, ma probabilmente inatteso. + +@cindex profilare programmi @command{awk}, dinamicamente +@cindex @command{gawk}, programma, profilazione dinamica +@cindex profilazione dinamica +Oltre a creare profili una volta completato il programma, +@command{gawk} pu@`o generare un profilo mentre @`e in esecuzione. +Questo @`e utile se il proprio programma @command{awk} entra in un ciclo +infinito e si vuol vedere cosa @`e stato eseguito. +Per usare questa funzionalit@`a, bisogna eseguire @command{gawk} con l'opzione +@option{--profile} in background: + +@example +$ @kbd{gawk --profile -f mioprog &} +[1] 13992 +@end example + +@cindex @command{kill}, comando@comma{} profilazione dinamica e +@cindex comando @command{kill}@comma{} profilazione dinamica e +@cindex @code{USR1}, segnale, per profilazione dinamica +@cindex @code{SIGUSR1}, segnale, per profilazione dinamica +@cindex segnali @code{USR1}/@code{SIGUSR1}, per profilazione +@noindent +La shell stampa un numero di job e il numero di ID del relativo processo; +in questo caso, 13992. Si usi il comando @command{kill} per inviare il +segnale @code{USR1} a @command{gawk}: + +@example +$ @kbd{kill -USR1 13992} +@end example + +@noindent +Come al solito, la versione profilata del programma @`e scritta nel file +@file{awkprof.out}, o in un file differente se ne viene specificato uno +con l'opzione @option{--profile}. + +Assieme al profilo regolare, come mostrato in precedenza, il file del profilo +include una traccia di ogni funzione attiva: + +@example +# `Stack' (Pila) Chiamate Funzione: + +# 3. paperino +# 2. pluto +# 1. pippo +# -- main -- +@end example + +Si pu@`o inviare a @command{gawk} il segnale @code{USR1} quante volte si vuole. +Ogni volta, il profilo e la traccia della chiamata alla funzione vengono +aggiunte in fondo al file di profilo creato. + +@cindex @code{HUP}, segnale, per profilazione dinamica +@cindex @code{SIGHUP}, segnale, per profilazione dinamica +@cindex segnali @code{HUP}/@code{SIGHUP}, per profilazione +Se si usa il segnale @code{HUP} invece del segnale @code{USR1}, @command{gawk} +genera il profilo e la traccia della chiamata alla funzione ed esce. + +@cindex @code{INT}, segnale (MS-Windows) +@cindex @code{SIGINT}, segnale (MS-Windows) +@cindex segnali @code{INT}/@code{SIGINT} (MS-Windows) +@cindex @code{QUIT}, segnale (MS-Windows) +@cindex @code{SIGQUIT}, segnale (MS-Windows) +@cindex segnali @code{QUIT}/@code{SIGQUIT} (MS-Windows) +Quando @command{gawk} viene eseguito sui sistemi MS-Windows, usa i segnali +@code{INT} e @code{QUIT} per generare il profilo, e nel +caso del segnale @code{INT}, @command{gawk} esce. Questo perch@'e +questi sistemi non prevedono il comando @command{kill}, per cui gli unici +segnali che si possono trasmettere a un programma sono quelli generati dalla +tastiera. Il segnale @code{INT} @`e generato dalle combinazioni di tasti +@kbd{Ctrl-c} o @kbd{Ctrl-BREAK}, mentre il segnale +@code{QUIT} @`e generato dalla combinazione di tasti @kbd{Ctrl-\}. + +Infine, @command{gawk} accetta anche un'altra opzione, @option{--pretty-print}. +Quando viene chiamato in questo modo, @command{gawk} fa una ``stampa elegante'' +del programma nel file @file{awkprof.out}, senza conteggi sull'esecuzione. + +@quotation NOTA +Una volta, l'opzione @option{--pretty-print} eseguiva anche il programma. +Ora non pi@`u. +@end quotation + +C'@`e una differenza significativa tra l'output creato durante la profilazione, e +quello creato durante la stampa elegante. L'output della stampa elegante +preserva i commenti originali che erano nel programma, anche se la loro +posizione pu@`o non corrispondere esattamente alle posizioni originali che +avevano nel codice sorgente.@footnote{@command{gawk} fa del suo meglio +per mantenere la distinzione tra commenti posti dopo delle istruzioni e +commenti su righe a s@'e stanti. Per limiti insiti nell'implementazione, +non sempre questo pu@`o avvenire in maniera corretta, in particolare nel +caso di istruzioni @code{switch}. I manutentori di @command{gawk} +sperano di poter migliorare la situazione in una futura versione.} + +Comunque, per una precisa scelta progettuale, l'output della profilazione +@emph{omette} i commenti del programma originale. Questo permette di +concentrarsi sui dati del conteggio di esecuzione ed evita la tentazione di +usare il profilatore per creare una stampa elegante. + +Oltre a ci@`o, l'output stampato in modo elegante non ha l'indentazione iniziale +che ha l'output della profilazione. Questo rende agevole la stampa elegante +del proprio codice una volta completato lo sviluppo, usando poi il risultato +come versione finale del programma. + +Poich@'e la rappresentazione interna del programma @`e formattata per +essere aderente al programma @command{awk} in questione, la profilatura +e la formattazione graziosa (opzione @option{--pretty-print}) disabilitano +automaticamente le optimizzazioni di default di @command{gawk}. + +La formattazione elegante mantiene anche il formato originale delle +costanti numeriche; se sono stati usati dei valori ottali o esadecimali +nel codice sorgente, questi compariranno nell'output nello stesso +formato con cui sono stati inseriti. + +@node Sommario funzionalit@`a avanzate +@section Sommario + +@itemize @value{BULLET} +@item +L'opzione @option{--non-decimal-data} fa s@`{@dotless{i}} che @command{gawk} tratti +i dati di input che hanno l'aspetto ottale ed esadecimale come valori ottali ed +esadecimali. L'opzione dovrebbe essere usata con prudenza o non usata affatto; +@`e preferibile l'uso di @code{strtonum()}. +Si noti che quest'opzione potrebbe sparire nelle prossime versioni di +@command{gawk}. + +@item +Si pu@`o prendere il completo controllo dell'ordinamento nello scorrere il +vettore con @samp{for (@var{indice} in @var{vettore})}, impostando +@code{PROCINFO["sorted_in"]} al nome di una funzione definita dall'utente che +fa il confronto tra elementi del vettore basandosi su indice e valore. + +@item +Analogamente, si pu@`o fornire il nome di una funzione di confronto definita +dall'utente come terzo argomento di @code{asort()} o di @command{asorti()} per +controllare come queste funzioni ordinano i vettori. O si pu@`o fornire una delle +stringhe di controllo predefinite che funzionano per +@code{PROCINFO["sorted_in"]}. + +@item +Si pu@`o usare l'operatore @samp{|&} per creare una @dfn{pipe} bidirezionale +verso un coprocesso. Si legge dal coprocesso con @code{getline}, ci si +scrive sopra con @code{print} o con @code{printf}. Usare @code{close()} +per bloccare il coprocesso completamente o, se necessario, chiudere le +comunicazioni bidirezionali in una direzione. + +@item +Usando degli speciali @value{FNS} con l'operatore @samp{|&}, si pu@`o aprire una +connessione TCP/IP (o UDP/IP) verso host remoti su internet. @command{gawk} +supporta sia IPv4 che IPv6. + +@item +Si possono generare profili del proprio programma con i conteggi del numero +di esecuzione di ogni singola +istruzione. Questo pu@`o essere d'aiuto nel determinare quali parti del programma +potrebbero portar via la maggior parte del tempo, consentendo cos@`{@dotless{i}} di +aggiustarli pi@`u agevolmente. Inviando il segnale @code{USR1} durante la +profilazione @command{gawk} scrive il profilo, includendo la +stack della chiamata alla funzione e prosegue nell'elaborazione. + +@item +Si pu@`o anche fare solo una ``stampa elegante'' del programma. + +@end itemize +@node Internazionalizzazione +@chapter Internazionalizzazione con @command{gawk} + +Tanto tempo fa i produttori di computer +scrivevano software che comunicava solo in inglese. +Col passare del tempo, i venditori di hardware e di software si sono +resi conto che se i loro sistemi avessero comunicato anche nelle lingue +materne di paesi dove non si parlava inglese, +ci@`o avrebbe avuto come risultato un incremento delle vendite. +Per questo motivo, l'internazionalizzazione e la localizzazione +di programmi e sistemi software @`e divenuta una pratica comune. + +@cindex internazionalizzazione, localizzazione +@cindex @command{gawk}, internazionalizzazione e, si veda internazionalizzazione +@cindex internazionalizzazione, localizzazione, @command{gawk} e +Per molti anni la possibilit@`a di fornire l'internazionalizzazione +era sostanzialmente limitata ai programmi scritti in C e C++. +Questo @value{CHAPTER} descrive la libreria @dfn{ad hoc} utilizzata da +@command{gawk} +per l'internazionalizzazione e anche il modo in cui le funzionalit@`a che +consentono l'internazionalizzazione sono rese disponibili da @command{gawk} +a ogni programma scritto in @command{awk}. +La disponibilit@`a dell'internazionalizzazione a livello di programma +@command{awk} offre ulteriore flessibilit@`a agli sviluppatori di software: +non sono pi@`u obbligati a scrivere in C o C++ quando l'internazionalizzazione +@`e necessaria in un programma. + +@menu +* I18N e L10N:: Internazionalizzazione e localizzazione. +* Utilizzare @command{gettext}:: Come funziona il comando GNU @command{gettext}. +* I18N per programmatore:: Funzionalit@`a per il programmatore. +* I18N per traduttore:: Funzionalit@`a per il traduttore. +* Esempio I18N:: Un semplice esempio di internazionalizzazione. +* Gawk internazionalizzato:: Anche @command{gawk} @`e internazionalizzato. +* Sommario I18N:: Sommario dell'internazionalizzazione. +@end menu + +@node I18N e L10N +@section Internazionalizzazione e localizzazione + +@cindex internazionalizzazione di programmi @command{awk} +@cindex localizzazione, si veda internazionalizzazione@comma{} localizzazione +@cindex localizzazione +@dfn{Internazionalizzazione} significa scrivere (o modificare) un programma +una volta sola, +in maniera tale che possa usare pi@`u di una lingua senza +bisogno di ulteriori modifiche al file sorgente. +@dfn{Localizzazione} +significa fornire i dati necessari perch@'e un programma +internazionalizzato sia in grado di funzionare con una data lingua. +Questi termini si riferiscono comunemente a funzionalit@`a quali la lingua +usata per stampare messaggi di errore, quella usata per leggere +risposte, e alle informazioni +relative al modo di leggere e di stampare dati di tipo numerico o valutario. + +@node Utilizzare @command{gettext} +@section Il comando GNU @command{gettext} + +@cindex internazionalizzare un programma +@cindex @command{gettext}, libreria +@cindex libreria @command{gettext} +@command{gawk} usa il comando GNU @command{gettext} per rendere disponibili +le proprie funzionalit@`a di internazionalizzazione. +L'attenzione del comando GNU @command{gettext} @`e rivolta principalmente +ai messaggi: stringhe di caratteri stampate da un programma, sia +direttamente sia usando la formattazione prevista dalle istruzioni +@code{printf} o @code{sprintf()}.@footnote{Per alcuni sistemi operativi, +la relativa versione di @command{gawk} +non supporta il comando GNU @command{gettext}. +Per questo motivo, queste funzionalit@`a non sono disponibili nel caso +si stia lavorando con uno di questi sistemi operativi. Siamo spiacenti.} + +@cindex portabilit@`a, libreria @command{gettext} e +Quando si usa il comando GNU @command{gettext}, ogni applicazione ha il +proprio @dfn{dominio di testo}. Questo @`e un nome unico come, +p.es., @samp{kpilot} o @samp{gawk}, +che identifica l'applicazione. +Un'applicazione completa pu@`o avere pi@`u componenti: programmi scritti +in C o C++, come pure script di @command{sh} o di @command{awk}. +Tutti i componenti usano lo stesso dominio di testo. + +Per andare sul concreto, si supponga di scrivere un'applicazione +chiamata @command{guide}. L'internazionalizzazione per quest'applicazione +pu@`o essere implementata seguendo nell'ordine i passi qui delineati: + +@enumerate +@item +Il programmatore esamina i sorgenti di tutti i componenti dell'applicazione +@command{guide} e prende nota di ogni stringa che potrebbe aver bisogno +di traduzione. +Per esempio, @code{"`-F': option required"} @`e una stringa che sicuramente +necessita di una traduzione. +Una tabella che contenga stringhe che sono nomi di opzioni @emph{non} +necessita di traduzione. +(P.es., l'opzione di @command{gawk} @option{--profile} +dovrebbe restare immutata, a prescindere dalla lingua locale). + +@cindex @code{textdomain()}, funzione (libreria C) +@cindex funzione @code{textdomain()} (libreria C) +@item +Il programmatore indica il dominio di testo dell'applicazione +(@command{"guide"}) alla libreria @command{gettext}, +chiamando la funzione @code{textdomain()}. + +@cindex @code{.pot}, file +@cindex file @code{.pot} +@cindex @dfn{portable object template} (.pot), file +@cindex file, @dfn{portable object template} (.pot) +@item +I messaggi dell'applicazione che vanno tradotti sono estratti dal codice +sorgente e messi in un file di tipo +@dfn{portable object template} +[modello di oggetto portabile] +di nome @file{guide.pot}, +che elenca le stringhe e le relative traduzioni. +Le traduzioni sono inizialmente vuote +(esiste la struttura che definisce la stringa tradotta, ma la stringa +tradotta @`e una stringa nulla). +Il messaggio originale (normalmente in inglese) @`e utilizzato come chiave +di riferimento per le traduzioni. + +@cindex @code{.po}, file +@cindex file @code{.po} +@cindex @dfn{portable object} file (.po) +@cindex file, @dfn{portable object} (.po) +@item +Per ogni lingua per cui sia disponibile un traduttore, il file +@file{guide.pot} @`e copiato in un file di tipo +@dfn{portable object} +[oggetto portabile] +(dal suffisso @code{.po}) +e le traduzioni sono effettuate su quel file, +che viene distribuito con l'applicazione. +Per esempio, potrebbe esserci un file @file{it.po} per la traduzione italiana. + +@cindex @code{.gmo}, file +@cindex file @code{.gmo} +@cindex @dfn{message object} file (.mo) +@cindex file, @dfn{message object} (.mo) +@item +Il file @file{.po} di ogni lingua @`e convertito in un formato binario, +detto @dfn{message object} (file @file{.gmo}). +Un file di tipo @dfn{message object} contiene i messaggi originali e le loro +traduzioni in un formato binario che facilita il ritrovamento delle +traduzioni quando l'applicazione viene eseguita. + +@item +Quando @command{guide} @`e compilato e installato, i file binari contenenti le +traduzioni sono installati in una directory standard. + +@cindex @code{bindtextdomain()}, funzione (libreria C) +@cindex funzione @code{bindtextdomain()} (libreria C) +@item +Durante la fase di prova e sviluppo, @`e possibile chiedere a @command{gettext} +di usare un file @file{.gmo} in una directory diversa da quella standard, +usando la funzione @code{bindtextdomain()}. + +@cindex @code{.gmo}, file, specificare la directory di +@cindex file @code{.gmo}, specificare la directory di +@cindex @dfn{message object} file (.mo), specificare la directory di +@cindex file, @dfn{message object} (.mo), specificare la directory di +@item +Quando viene eseguito, il programma @command{awk} @command{guide} cerca ogni +stringa da tradurre facendo una chiamata a @code{gettext()}. La stringa +ricevuta in ritorno @`e la stringa tradotta, se @`e stata trovata, o la stringa +originale, se una traduzione non @`e disponibile. + +@item +Se necessario, @`e possibile procurarsi dei messaggi tradotti da un dominio di +testo diverso da quello proprio dell'applicazione, senza dover altalenare fra +questo secondo dominio e quello dell'applicazione. +@end enumerate + +@cindex @code{gettext()}, funzione (libreria C) +@cindex funzione @code{gettext()} (libreria C) +In C (o C++), la marcatura della stringa la ricerca dinamica +della traduzione si fanno inserendo ogni stringa da tradurre in una chiamata +a @code{gettext()}: + +@example +printf("%s", gettext("Don't Panic!\n")); +@end example + +Gli strumenti software che estraggono messaggi dal codice sorgente +individuano tutte le stringhe racchiuse nelle chiamate a @code{gettext()}. + +@cindex @code{_} (trattino basso), macro C +@cindex trattino basso (@code{_}), macro C +Gli sviluppatori del comando GNU @command{gettext}, riconoscendo che +continuare a immettere @samp{gettext(@dots{})} @`e sia faticoso che poco +elegante da vedere, usano la macro @samp{_} (un trattino basso) per +facilitare la cosa: + +@example +/* Nel file di intestazione standard: */ +#define _(str) gettext(str) + +/* Nel testo del programma: */ +printf("%s", _("Don't Panic!\n")); +@end example + +@cindex internazionalizzazione, localizzazione, categorie di localizzazione +@cindex @command{gettext}, libreria, categorie di localizzazione +@cindex libreria @command{gettext}, categorie di localizzazione +@cindex categorie di localizzazione +@noindent +Questo permette di ridurre la digitazione extra a solo tre caratteri per +ogni stringa da tradurre e inoltre migliora di molto la leggibit@`a. + +Ci sono @dfn{categorie} di localizzazione per tipi diversi di informazioni +legate a una particolare localizzazione. +Le categorie di localizzazione note a @command{gettext} sono: + +@table @code +@cindex @code{LC_MESSAGES}, categoria di localizzazione +@cindex categoria di localizzazione @code{LC_MESSAGES} +@item LC_MESSAGES +Testo dei messaggi. Questa @`e la categoria di default usata all'interno di +@command{gettext}, ma @`e possibile specificarne esplicitamente una differente, +se necessario. (Questo non @`e quasi mai necessario.) + +@cindex ordinare caratteri in lingue differenti +@cindex @code{LC_COLLATE}, categoria di localizzazione +@cindex categoria di localizzazione @code{LC_COLLATE} +@item LC_COLLATE +Informazioni sull'ordinamento alfabetico (cio@`e, come caratteri diversi e/o +gruppi di carattere sono ordinati in un dato linguaggio). +@c ad esempio i vari caratteri accentati in italiano, vanno ordinati +@c insieme alla loro lettera "principale" (e @`e @'e). + +@cindex @code{LC_CTYPE}, categoria di localizzazione +@cindex categoria di localizzazione @code{LC_CTYPE} +@item LC_CTYPE +Informazioni sui singoli caratteri (alfabetico, numerico, maiuscolo +o minuscolo, etc.), come pure sulla codifica dei caratteri. +@ignore +In June 2001 Bruno Haible wrote: +- Description of LC_CTYPE: It determines both + 1. character encoding, + 2. character type information. + (For example, in both KOI8-R and ISO-8859-5 the character type information + is the same - cyrillic letters could as 'alpha' - but the encoding is + different.) +@end ignore +Quest'informazione @`e utilizzata per stabilire le classi di caratteri come +definite nello standard POSIX, nelle espressioni regolari, +come p. es. @code{/[[:alnum:]]/} +(@pxref{Espressioni tra parentesi quadre}). + +@cindex informazioni di tipo monetario, localizzazione +@cindex monete, simboli di, nella localizzazione +@cindex simboli di monete, nella localizzazione +@cindex monete, rappresentazioni di, nella localizzazione +@cindex rappresentazioni di monete, nella localizzazione +@cindex @code{LC_MONETARY}, categoria di localizzazione +@cindex categoria di localizzazione @code{LC_MONETARY} +@item LC_MONETARY +Le informazioni di tipo monetario, quali il simbolo della moneta, e se +il simbolo va prima o dopo il valore numerico. + +@cindex @code{LC_NUMERIC}, categoria di localizzazione +@cindex categoria di localizzazione @code{LC_NUMERIC} +@item LC_NUMERIC +Informazioni di tipo numerico, quali il carattere da usare per separare le +cifre decimali e quello per separare le migliaia.@footnote{Gli americani usano +una virgola ogni tre cifre decimali, e un punto per separare la parte decimale +di un numero, mentre molti europei (fra cui gli italiani) fanno esattamente +l'opposto: 1,234.56 invece che 1.234,56.} + +@cindex tempo, localizzazione e +@cindex date, informazioni relative alla localizzazione +@cindex @code{LC_TIME}, categoria di localizzazione +@cindex categoria di localizzazione @code{LC_TIME} +@item LC_TIME +Informazioni relative alle date e alle ore, +come l'uso di ore nel formato a 12 ore oppure a 24 ore, il mese stampato +prima o dopo il giorno in una data, le abbreviazioni dei mesi nella lingua +locale, e cos@`{@dotless{i}} via. + +@cindex @code{LC_ALL}, categoria di localizzazione +@cindex categoria di localizzazione @code{LC_ALL} +@item LC_ALL +Tutte le categorie viste sopra. (Non molto utile nel contesto del comando +@command{gettext}.) +@end table + +@quotation NOTA +@cindex @env{LANGUAGE}, variabile d'ambiente +@cindex variabile d'ambiente @env{LANGUAGE} +Come descritto in @ref{Localizzazioni}, le variabili d'ambiente +che hanno lo stesso nome delle categorie di localizzazione +(@env{LC_CTYPE}, @env{LC_ALL}, etc.) influenzano il comportamento di +@command{gawk} (e quello di altri programmi di utilit@`a). + +Solitamente, queste variabili influenzano anche il modo con cui +la libreria @code{gettext} trova le traduzioni. Tuttavia, la +variabile d'ambiente @env{LANGUAGE} prevale sulle variabili +della famiglia @env{LC_@var{xxx}}. Molti sistemi GNU/Linux possono +aver definito questa variabile senza esplicitamente notificarlo +all'utente, e questo potrebbe far s@`{@dotless{i}} che @command{gawk} non riesca a +trovare le traduzioni corrette. Se si incontra questa situazione, +occorre controllare se la variabile d'ambiente @env{LANGUAGE} @`e +definita, e, in questo caso, va usato il comando @command{unset} +per rimuoverla. +@end quotation + +Per il test di traduzioni dei messaggi inviati da @command{gawk} stesso, si pu@`o +impostare la variabile d'ambiente @env{GAWK_LOCALE_DIR}. Si veda la +documentazione per la funzione C @code{bindtextdomain()}, e si veda anche +@ref{Altre variabili d'ambiente}. + +@node I18N per programmatore +@section Internazionalizzare programmi @command{awk} +@cindex programmi @command{awk}, internazionalizzare +@cindex internazionalizzazione di programmi @command{awk} + +@command{gawk} prevede le seguenti variabili per l'internazionalizzazione: + +@table @code +@cindex @code{TEXTDOMAIN}, variabile +@cindex variabile @code{TEXTDOMAIN} +@item TEXTDOMAIN +Questa variabile indica il dominio di testo dell'applicazione. +Per compatibilit@`a con il comando GNU @command{gettext}, il valore di default +@`e @code{"messages"}. + +@cindex internazionalizzazione, localizzazione, stringhe marcate +@cindex stringhe, marcare per localizzazione +@item _"questo @`e un messaggio da tradurre" +Costanti di tipo stringa marcate con un trattino basso iniziale +sono candidate per essere tradotte al momento dell'esecuzione del +programma @command{gawk}. +Costanti di tipo stringa non precedute da un trattino basso non +verranno tradotte. +@end table + +@command{gawk} fornisce le seguenti funzioni al servizio +dell'internazionalizzazione: + +@table @code +@cindexgawkfunc{dcgettext} +@item @code{dcgettext(@var{string}} [@code{,} @var{dominio} [@code{,} @var{categoria}]]@code{)} +Restituisce la traduzione di @var{stringa} nel +dominio di testo @var{dominio} per la categoria di localizzazione @var{categoria}. +Il valore di default per @var{dominio} @`e il valore corrente di @code{TEXTDOMAIN}. +Il valore di default per @var{categoria} @`e @code{"LC_MESSAGES"}. + +Se si assegna un valore a @var{categoria}, dev'essere una stringa uguale a +una delle categorie di localizzazione note, descritte +@ifnotinfo +nella precedente @value{SECTION}. +@end ifnotinfo +@ifinfo +@ref{Utilizzare @command{gettext}}. +@end ifinfo +Si deve anche specificare un dominio di testo. Si usi @code{TEXTDOMAIN} se +si desidera usare il dominio corrente. + +@quotation ATTENZIONE +L'ordine degli argomenti per la versione @command{awk} +della funzione @code{dcgettext()} @`e differente, per una scelta di progetto, +dall'ordine degli argomenti passati alla funzione C che ha lo stesso nome. +L'ordine della versione @command{awk} @`e stato scelto per amore di +semplicit@`a e per consentire di avere dei valori di default per gli +argomenti che fossero il pi@`u possibile simili, come stile, a quello di +@command{awk}. +@end quotation + +@cindexgawkfunc{dcngettext} +@item @code{dcngettext(@var{stringa1}, @var{stringa2}, @var{numero}} [@code{,} @var{dominio} [@code{,} @var{categoria}]]@code{)} +Restituisce la forma, singolare o plurale, da usare a seconda del valore +di @var{numero} per la +traduzione di @var{stringa1} e @var{stringa2} nel dominio di testo +@var{dominio} per la categoria di localizzazione @var{categoria}. +@var{stringa1} @`e la variante al singolare in inglese di un messaggio, +e @var{stringa2} @`e la variante al plurale in inglese dello stesso messaggio. +Il valore di default per @var{dominio} @`e il valore corrente di @code{TEXTDOMAIN}. +Il valore di default per @var{categoria} @`e @code{"LC_MESSAGES"}. + +Valgono le stesse osservazioni riguardo all'ordine degli argomenti +fatte a proposito della funzione @code{dcgettext()}. + +@cindex @code{.gmo}, file, specificare la directory di +@cindex file @code{.gmo}, specificare la directory di +@cindex @dfn{message object} file (.mo), specificare la directory di +@cindex file, @dfn{message object} (.mo), specificare la directory di +@cindexgawkfunc{bindtextdomain} +@item @code{bindtextdomain(@var{directory}} [@code{,} @var{dominio} ]@code{)} +Cambia la directory nella quale +@command{gettext} va a cercare i file @file{.gmo}, per il caso in cui questi +non possano risiedere nelle posizioni standard +(p.es., in fase di test). +Restituisce la directory alla quale @var{dominio} @`e ``collegato''. + +Il @var{dominio} di default @`e il valore di @code{TEXTDOMAIN}. +Se l'argomento @var{directory} @`e impostato alla stringa nulla (@code{""}), +@code{bindtextdomain()} restituisce il collegamento corrente applicabile +al @var{dominio} specificato. +@end table + +Per usare queste funzionalit@`a in un programma @command{awk}, +va seguita la procedura qui indicata: + +@enumerate +@cindex @code{BEGIN}, criterio di ricerca, variabile @code{TEXTDOMAIN} e +@cindex criterio di ricerca @code{BEGIN}, variabile @code{TEXTDOMAIN} e +@cindex @code{TEXTDOMAIN}, variabile, criterio di ricerca @code{BEGIN} e +@cindex variabile @code{TEXTDOMAIN}, criterio di ricerca @code{BEGIN} e +@item +Impostare la variabile @code{TEXTDOMAIN} al dominio di testo del +programma. @`E meglio fare ci@`o all'interno di una regola @code{BEGIN} +(@pxref{BEGIN/END}), +ma si pu@`o anche fare dalla riga di comando, usando l'opzione @option{-v} +(@pxref{Opzioni}): + +@example +BEGIN @{ + TEXTDOMAIN = "guide" + @dots{} +@} +@end example + +@cindex @code{_} (trattino basso), stringa traducibile +@cindex trattino basso (@code{_}), stringa traducibile +@item +Marcare tutte le stringhe traducibili anteponendo loro un +trattino basso (@samp{_}). Il trattino @emph{deve} essere adiacente ai +doppi apici di apertura della stringa. Per esempio: + +@example +print _"hello, world" +x = _"you goofed" +printf(_"Number of users is %d\n", nusers) +@end example + +@item +Se le stringhe da visualizzare sono create dinamicamente, @`e ancora possibile +tradurle, usando la funzione predefinita @code{dcgettext()}:@footnote{I miei +ringraziamenti a Bruno Haible per questo esempio.} + +@example +if (assonnato) + messaggio = dcgettext("%d clienti mi scocciano\n", "adminprog") +else + messaggio = dcgettext("mi diverto con %d clienti\n", "adminprog") +printf(messaggio, numero_clienti) +@end example + +In questo esempio, la chiamata a @code{dcgettext()} specifica un diverso +dominio di testo (@code{"adminprog"}) in cui trovare il +messaggio, ma usa la categoria di default @code{"LC_MESSAGES"}. + +Il precedente esempio funziona solo se @code{numero_clienti} @`e un numero maggiore +di uno. +Per questo esempio sarebbe pi@`u appropriato usare la funzione @code{dcngettext()}: + +@example +if (assonnato) + messaggio = dcngettext("%d cliente mi scoccia\n", + "%d clienti mi scocciano\n", + numero_clienti, "adminprog") +else + messaggio = dcngettext("mi diverto con %d cliente\n", + "mi diverto con %d clienti\n", + numero_clienti, "adminprog") +printf(messaggio, numero_clienti) +@end example + + +@cindex @code{LC_MESSAGES}, categoria di localizzazione, funzione @code{bindtextdomain()} di (@command{gawk}) +@item +In fase di sviluppo, si pu@`o scegliere di tenere il file @file{.gmo} +in una directory a parte, solo per provarlo. Ci@`o si fa +con la funzione predefinita @code{bindtextdomain()}: + +@example +BEGIN @{ + TEXTDOMAIN = "guide" # dominio di testo regolare + if (Testing) @{ + # dove trovare il file in prova + bindtextdomain("testdir") + # joe si occupa del programma adminprog + bindtextdomain("../joe/testdir", "adminprog") + @} + @dots{} +@} +@end example + +@end enumerate + +@xref{Esempio I18N} +per un programma di esempio che illustra i passi da seguire per creare +e usare traduzioni nei programmi @command{awk}. + +@node I18N per traduttore +@section Traduzione dei programmi @command{awk} + +@cindex @code{.po}, file +@cindex file @code{.po} +@cindex @dfn{portable object} file (.po) +@cindex file, @dfn{portable object} (.po) +Dopo aver marcato le stringhe che si desidera tradurre in un programma, +queste vanno estratte per creare il file iniziale @file{.pot}. +Durante la traduzione, @`e spesso utile modificare l'ordine nel quale +gli argomenti passati a @code{printf} vengono stampati. + +L'opzione da riga di comando @option{--gen-pot} di @command{gawk} serve a +estrarre i messaggi, ed @`e esposta qui di seguito. +Dopo di che, verr@`a illustrata la possibilit@`a di modificare l'ordine +in cui l'istruzione @code{printf} stampa gli argomenti che le sono passati +in fase di esecuzione. + +@menu +* Estrazione di stringhe:: Estrarre stringhe marcate. +* Ordinamento di printf:: Riordinare argomenti @code{printf} +* Portabilit@`a nell'I18N:: Problemi di portabilit@`a a livello di @command{awk}. +@end menu + +@node Estrazione di stringhe +@subsection Estrarre stringhe marcate +@cindex stringhe, estrazione di +@cindex stringhe marcate, estrazione di +@cindex @option{--gen-pot}, opzione +@cindex opzione @option{--gen-pot} +@cindex opzioni sulla riga di comando, estrazione stringhe +@cindex riga di comando, opzioni, estrazione stringhe +@cindex stringhe marcate, estrazione di (internazionalizzazione) +@cindex marcate, estrazione di stringhe (internazionalizzazione) +@cindex estrazione di stringhe marcate (internazionalizzazione) + +@cindex @option{--gen-pot}, opzione +@cindex opzione @option{--gen-pot} +Una volta che il programma @command{awk} funziona, e tutte le stringhe +sono state marcate ed @`e stato impostato (e forse fissato) il dominio di +testo, @`e ora di preparare le traduzioni. +Per prima cosa, usando l'opzione di riga di comando @option{--gen-pot}, +si crea il file iniziale @file{.pot}: + +@example +gawk --gen-pot -f guide.awk > guide.pot +@end example + +@cindex @code{xgettext}, programma di utilit@`a +@cindex programma di utilit@`a @code{xgettext} +Quando viene chiamato specificando @option{--gen-pot}, @command{gawk} non +esegue il programma. Il programma viene esaminato come al solito, e tutte +le stringhe che sono state marcate per essere tradotte vengono scritte nello +standard output, nel formato di un file Portable Object di GNU +@command{gettext}. +L'output comprende anche quelle stringhe costanti che appaiono come primo +argomento della funzione @code{dcgettext()} o come primo e secondo +argomento della funzione @code{dcngettext()}.@footnote{Il comando di utilit@`a +@command{xgettext} che fa parte del pacchetto distribuito come +@command{gettext} @`e in grado di gestire i file di tipo @file{.awk}.} +Il file @file{.pot} cos@`{@dotless{i}} generato +andrebbe distribuito insieme al programma @command{awk}; i traduttori +potranno eventualmente utilizzarlo per preparare delle traduzioni, le quali +potranno a loro volta essere distribuite. +@xref{Esempio I18N} +per una lista esauriente dei passi necessari per creare e testare +traduzioni per il programma @command{guide}. + +@node Ordinamento di printf +@subsection Riordinare argomenti di @code{printf} + +@cindex @code{printf}, istruzione, specificatori di posizione +@cindex istruzione @code{printf}, specificatori posizionali +@cindex posizionali, specificatori, istruzione @code{printf} +@cindex specificatori posizionali, istruzione @code{printf} +Le stringhe di formattazione per @code{printf} e @code{sprintf()} +(@pxref{Printf}) +hanno un problema speciale con le traduzioni. +Si consideri il seguente esempio:@footnote{Questo esempio @`e preso in +prestito dal manuale del comando GNU @command{gettext}.} + +@example +printf(_"String `%s' has %d characters\n", + string, length(string))) +@end example + +Una possibile traduzione in italiano di questo messaggio potrebbe essere: + +@example +"%d @`e la lunghezza della stringa `%s'\n" +@end example + +Il problema dovrebbe essere ovvio: l'ordine delle specifiche di +formattazione @`e differente da quello originale! +@code{gettext()}, che pure pu@`o restituire la stringa tradotta +in fase di esecuzione, non @`e in grado di cambiare l'ordine degli argomenti +nella chiamata a @code{printf}. + +Per risolvere questo problema, gli specificatori di formato di @code{printf} +possono avere un elemento in pi@`u, facoltativo, detto @dfn{specificatore +posizionale}. Per esempio: + +@example +"%2$d @`e la lunghezza della stringa `%1$s'\n" +@end example + +Qui, lo specificatore posizionale consiste in un numero intero, che indica +quale argomento utilizzare, seguito da un carattere @samp{$}. +I numeri partono da uno, e la stringa di formattazione vera e propria +@emph{non} @`e inclusa. Quindi, nell'esempio seguente, @samp{stringa} @`e +il primo argomento e @samp{length(stringa)} @`e il secondo: + +@example +$ @kbd{gawk 'BEGIN @{} +> @kbd{stringa = "Non v\47allarmate!"} +> @kbd{printf "%2$d caratteri compongono \"%1$s\"\n",} +> @kbd{stringa, length(stringa)} +> @kbd{@}'} +@print{} 16 caratteri compongono "Non v\47allarmate!" +@end example + +Se presenti, gli specificatori posizionali precedono, nella specifica di +formato, i flag, la larghezza del campo e/o la precisione. + +Gli specificatori posizionali possono essere usati anche se si specifica una +larghezza dinamica dei campi, e della capacit@`a di precisione: + +@example +$ @kbd{gawk 'BEGIN @{} +> @kbd{printf("%*.*s\n", 10, 20, "hello")} +> @kbd{printf("%3$*2$.*1$s\n", 20, 10, "hello")} +> @kbd{@}'} +@print{} hello +@print{} hello +@end example + +@quotation NOTA +Se si usa @samp{*} con uno specificatore posizionale, il carattere @samp{*} +viene per primo, seguito dal numero che indica la posizione, a sua volta +seguito dal @samp{$}. +Ci@`o pu@`o parere poco intuitivo. +@end quotation + +@cindex istruzione @code{printf}, specificatori posizionali, frammisti a formati standard +@cindex @code{printf}, istruzione, specificatori posizionali, frammisti a formati standard +@cindex specificatori posizionali, istruzione @code{printf}, frammisti a formati standard +@cindex formato, specificatori di, frammisti a specificatori posizionali non standard +@cindex specificatori di formato, frammisti a specificatori posizionali non standard +@command{gawk} non consente di mischiare specificatori di formato standard +con altri contenenti degli specificatori posizionali in una stessa stringa di +formato: + +@example +$ @kbd{gawk 'BEGIN @{ printf "%d %3$s\n", 1, 2, "ciao" @}'} +@error{} gawk: riga com.:1: fatale: `count$' va usato per tutti +@error{} i formati o per nessuno +@end example + +@quotation NOTA +Ci sono alcuni casi patologici in cui @command{gawk} potrebbe non inviare +alcun messaggio diagnostico, anche quando sarebbe necessario. +In tali casi, l'output pu@`o non essere quello atteso. +Rimane sempre una pessima idea quella di tentare di mischiare i formati, +anche se @command{gawk} non riesce ad accorgersene. +@end quotation + +Sebbene gli specificatori posizionali possano essere usati direttamente nei +programmi @command{awk}, il motivo per cui sono stati introdotti @`e perch@'e +siano d'aiuto nel produrre traduzioni corrette della stringa di +formattazione in lingue differenti da quella nella quale il programma @`e stato +originariamente scritto. + +@node Portabilit@`a nell'I18N +@subsection Problemi di portabilit@`a a livello di @command{awk} + +@cindex portabilit@`a, internazionalizzazione e +@cindex internazionalizzazione, localizzazione, portabilit@`a e +Le funzionalit@`a di internazionalizzazione di @command{gawk} sono state +appositamente implementate per avere il minimo impatto possibile sulla +portabilit@`a, verso altre versioni di @command{awk}, dei programmi +@command{awk} che ne fanno uso. +Si consideri questo programma: + +@example +BEGIN @{ + TEXTDOMAIN = "guide" + if (Test_Guide) # da impostare tramite -v + bindtextdomain("/test/guide/messages") + print _"don't panic!" +@} +@end example + +@noindent +Per il modo in cui @`e scritto, non funzioner@`a con altre versioni di +@command{awk}. +Tuttavia, @`e in realt@`a quasi portabile, e richiede modifiche minime: + +@itemize @value{BULLET} +@cindex @code{TEXTDOMAIN}, variabile, portabilit@`a e +@cindex variabile @code{TEXTDOMAIN}, portabilit@`a e +@item +Le assegnazioni di valori a @code{TEXTDOMAIN} non avranno effetto alcuno, +perch@'e @code{TEXTDOMAIN} non @`e una variabile speciale in altre +implementazioni di @command{awk}. + +@item +Versioni Non-GNU di @command{awk} considerano le stringhe marcate +come la concatenazione di una variabile di nome @code{_} con la stringa che +viene subito dopo.@footnote{Questo @`e +un buon materiale per una gara di ``Oscurit@`a @command{awk}''.} +Tipicamente, la variabile @code{_} ha come valore la stringa nulla +(@code{""}), il che produce come risultato la stringa +originale. + +@item +Definendo delle funzioni ``fittizie'' per sostituire @code{dcgettext()}, +@code{dcngettext()} e @code{bindtextdomain()}, il programma @command{awk} +pu@`o essere reso eseguibile, ma +tutti i messaggi verranno inviati nella lingua originale del programma. +Per esempio: + +@cindex @code{bindtextdomain()}, funzione (@command{gawk}), portabilit@`a e +@cindex funzione @code{bindtextdomain()} (@command{gawk}), portabilit@`a e +@cindex @code{dcgettext()}, funzione (@command{gawk}), portabilit@`a e +@cindex funzione @code{dcgettext()} (@command{gawk}), portabilit@`a e +@cindex @code{dcngettext()}, funzione (@command{gawk}), portabilit@`a e +@cindex funzione @code{dcngettext()} (@command{gawk}), portabilit@`a e +@example +@c file eg/lib/libintl.awk +function bindtextdomain(dir, domain) +@{ + return dir +@} + +function dcgettext(string, domain, category) +@{ + return string +@} + +function dcngettext(string1, string2, number, domain, category) +@{ + return (number == 1 ? string1 : string2) +@} +@c endfile +@end example + +@item +L'uso di specificazioni posizionali in @code{printf} o +@code{sprintf()} @emph{non} @`e portabile. +Per supportare @code{gettext()} nella programmazione in linguaggio C, +molte versioni C di @code{sprintf()} supportano specificatori posizionali. +Ma la cosa funziona solo se nella chiamata di funzione sono stati specificati +argomenti a sufficienza. Molte +versioni di @command{awk} passano i formati e gli argomenti di @code{printf}, +senza modificarli, alla funzione di libreria in linguaggio C @code{sprintf()}, +ma solo un formato e un argomento alla volta. Quel che succede se si usa una +specificazione posizionale resta indeterminato. +Tuttavia, poich@'e le specificazioni posizionali sono usate principalmente +per le stringhe di formattazione @emph{tradotte}, e poich@'e le versioni +non-GNU di @command{awk} non utilizzano mai le stringhe tradotte, ci@`o non +dovrebbe, in pratica, causare problemi. +@end itemize + +@node Esempio I18N +@section Un semplice esempio di internazionalizzazione. + +Vediamo ora un esempio dettagliato di come internazionalizzare e localizzare +un semplice programma @command{awk}, usando come nostro programma sorgente +originale il file @file{guide.awk}: + +@example +@c file eg/prog/guide.awk +BEGIN @{ + TEXTDOMAIN = "guide" + bindtextdomain(".") # per la fase di test + print _"Don't Panic" + print _"The Answer Is", 42 + print "Pardon me, Zaphod who?" +@} +@c endfile +@end example + +@noindent +Eseguire @samp{gawk --gen-pot} per creare il file @file{.pot}: + +@example +$ @kbd{gawk --gen-pot -f guide.awk > guide.pot} +@end example + +@noindent +Questo produce: + +@example +@c file eg/data/guide.po +#: guide.awk:4 +msgid "Don't Panic" +msgstr "" + +#: guide.awk:5 +msgid "The Answer Is" +msgstr "" + +@c endfile +@end example + +Questo modello di @dfn{portable object} va salvato e riutilizzato per ogni +lingua in cui l'applicazione viene tradotta. La stringa @code{msgid} @`e +seguita dalla stringa originale da tradurre, e la stringa @code{msgstr} +conterr@`a la traduzione. + +@quotation NOTA +Le stringhe non aventi come prefisso un trattino basso non sono inserite +nel file @file{guide.pot}. +@end quotation + +Successivamente, i messaggi devono essere tradotti. +Questa @`e una traduzione in un ipotetico dialetto dell'inglese, +chiamato ``Mellow'':@footnote{Forse sarebbe meglio chiamarlo +``Hippy.'' Meglio non indagare oltre.} + +@example +@group +$ @kbd{cp guide.pot guide-mellow.po} +@var{Aggiungere traduzioni al file} guide-mellow.po @dots{} +@end group +@end example + +@noindent +Ecco le traduzioni: + +@example +@c file eg/data/guide-mellow.po +#: guide.awk:4 +msgid "Don't Panic" +msgstr "Hey man, relax!" + +#: guide.awk:5 +msgid "The Answer Is" +msgstr "Like, the scoop is" + +@c endfile +@end example + +@cindex Linux +@cindex GNU/Linux +Il passo successivo @`e di creare la directory che contenga il file binario +con le traduzioni dei messaggi (file .mo [message object]) e +creare in quella directory il file @file{guide.mo}. +Si presume che il file in questione debba essere usato nella localizzazione +@code{en_US.UTF-8}, perch@'e si deve usare un nome di localizzazione che sia +noto alle routine del comando C @command{gettext}. +La disposizione delle directory qui utilizzata @`e standard per il comando +GNU @command{gettext} sui sistemi GNU/Linux. Altre versioni di +@command{gettext} possono usare una disposizione differente: + +@example +$ @kbd{mkdir en_US.UTF-8 en_US.UTF-8/LC_MESSAGES} +@end example + +@cindex @code{.po}, file, conversione in @code{.mo} +@cindex file @code{.po}, conversione in @code{.mo} +@cindex @code{.mo}, file, conversione da @code{.po} +@cindex file @code{.mo}, conversione da @code{.po} +@cindex @dfn{portable object} file (.po), conversione in @dfn{message object} file +@cindex file, @dfn{portable object} (.po), conversione in @dfn{message object} file +@cindex @dfn{message object} file (.mo), conversione da @dfn{portable object} file +@cindex file, @dfn{message object} (.mo), conversione da @dfn{portable object} file +@cindex @command{msgfmt}, programma di utilit@`a +@cindex programma di utilit@`a @command{msgfmt} +Il programma di utilit@`a @command{msgfmt} effettua la conversione dal file +leggibile, in formato testo, @file{.po} nel file, in formato binario, +@file{.mo}. +Per default, @command{msgfmt} crea un file di nome @file{messages}. +A questo file dev'essere assegnato un nome appropriato, e va messo nella +directory predisposta (usando l'opzione @option{-o}) in modo che +@command{gawk} sia in grado di trovarlo: + +@example +$ @kbd{msgfmt guide-mellow.po -o en_US.UTF-8/LC_MESSAGES/guide.mo} +@end example + +Infine, eseguiamo il programma per provare se funziona: + +@example +$ @kbd{gawk -f guide.awk} +@print{} Hey man, relax! +@print{} Like, the scoop is 42 +@print{} Pardon me, Zaphod who? +@end example + +Se le tre funzioni che rimpiazzano @code{dcgettext()}, @code{dcngettext()}, +e @code{bindtextdomain()} +(@pxref{Portabilit@`a nell'I18N}) +sono contenute in un file di nome @file{libintl.awk}, +@`e possibile eseguire @file{guide.awk} senza modificarlo, nel modo seguente: + +@example +$ @kbd{gawk --posix -f guide.awk -f libintl.awk} +@print{} Don't Panic +@print{} The Answer Is 42 +@print{} Pardon me, Zaphod who? +@end example + +@node Gawk internazionalizzato +@section @command{gawk} stesso @`e internazionalizzato + +Il comando @command{gawk} stesso @`e stato internazionalizzato +usando il pacchetto GNU @command{gettext}. +(GNU @command{gettext} @`e descritto in +maniera esauriente in +@ifinfo +@inforef{Top, , GNU @command{gettext} utilities, gettext, GNU @command{gettext} utilities}.) +@end ifinfo +@ifnotinfo +@uref{http://www.gnu.org/software/gettext/manual/, +@cite{GNU @command{gettext} utilities}}.) +@end ifnotinfo +Al momento in cui questo libro @`e stato scritto, la versione pi@`u recente di +GNU @command{gettext} @`e +@uref{ftp://ftp.gnu.org/gnu/gettext/gettext-0.19.4.tar.gz, +@value{PVERSION} 0.19.4}. + +Se esiste una traduzione dei messaggi di @command{gawk}, +@command{gawk} invia messaggi, avvertimenti, ed errori fatali +utilizzando la lingua locale. + +@node Sommario I18N +@section Sommario +@itemize @value{BULLET} +@item +Internazionalizzazione significa scrivere un programma in modo che +possa interagire in molte lingue senza che sia necessario cambiare il codice +sorgente. +Localizzazione significa fornire i dati necessari perch@'e un programma +internazionalizzato possa interagire usando una determinata lingua. + +@item +@command{gawk} usa il comando GNU @command{gettext} per consentire +l'internazionalizzazione e la localizzazione di programmi @command{awk}. +Un dominio di testo di un programma identifica il programma, e consente di +raggruppare tutti i messaggi e gli altri dati del programma in un solo posto. + +@item +Si marcano le stringhe in un programma da tradurre preponendo loro un +trattino basso. Una volta fatto questo, queste stringhe sono estratte +in un file @file{.pot}. Questo file @`e copiato, per ogni lingua, in un file +@file{.po} e i file @file{.po} sono +compilati in file @file{.gmo} che saranno usati in fase di +esecuzione del programma. + +@item +@`E possibile usare specificazioni posizionali con le istruzioni +@code{sprintf()} e @code{printf} per modificare la posizione del valore +degli argomenti nelle stringhe di formato e nell'output. Ci@`o @`e utile nella +traduzione di stringhe di +formattazione dei messaggi. + +@item +Le funzionalit@`a di internazionalizzazione sono state progettate in modo +da poter essere facilmente gestite in un programma @command{awk} standard. + +@item +Anche il comando @command{gawk} @`e stato internazionalizzato e viene +distribuito con traduzioni in molte lingue dei messaggi inviati in fase di +esecuzione. + +@end itemize + + +@node Debugger +@chapter Effettuare il debug dei programmi @command{awk} +@cindex debug dei programmi @command{awk} + +@c The original text for this chapter was contributed by Efraim Yawitz. +@c FIXME: Add more indexing. + +Sarebbe bello se i programmi per il calcolatore funzionassero perfettamente la +prima volta che vengono eseguiti, ma nella vita reale questo accade raramente, +qualunque sia la complessit@`a dei programmi. Perci@`o la maggior parte dei +linguaggi di programmazione hanno a disposizione degli strumenti che facilitano +la ricerca di errori (@dfn{debugging}) nei programmi, e @command{awk} non fa +eccezione. + +Il @dfn{debugger} di @command{gawk} @`e di proposito costruito sul modello del +debugger da riga di comando +@uref{http://www.gnu.org/software/gdb/, GNU Debugger (GDB)}. +Se si ha familiarit@`a con GDB, sar@`a facile imparare come usare @command{gawk} +per eseguire il debug dei propri programmi. + +@menu +* Debugging:: Introduzione al debugger di @command{gawk}. +* Esempio di sessione di debug:: Esempio di sessione di debug. +* Lista dei comandi di debug:: Principali comandi di debug. +* Supporto per Readline:: Supporto per Readline. +* Limitazioni:: Limitazioni e piani per il futuro. +* Sommario sul debug:: Sommario sul debug. +@end menu + +@node Debugging +@section Introduzione al debugger di @command{gawk} + +Questa @value{SECTION}, dopo un'introduzione sul debug in generale, inizia +la trattazione del debug in @command{gawk}. + +@menu +* Nozioni sul debug:: Generalit@`a sul debug. +* Terminologia nel debug:: Ulteriori nozioni sul debug. +* Debug di Awk:: Eseguire il debug di Awk. +@end menu + +@node Nozioni sul debug +@subsection Generalit@`a sul debug + +(Se si sono usati dei debugger in altri linguaggi, si pu@`o andare direttamente +alla @ref{Debug di Awk}.) + +Naturalmente, un programma di debug non pu@`o correggere gli errori al posto del +programmatore, perch@'e non pu@`o sapere quello che il programmatore o gli utenti +considerano un ``bug'' e non una ``funzionalit@`a''. (Talvolta, anche noi umani +abbiamo difficolt@`a nel determinarlo.) +In quel caso, cosa ci si pu@`o aspettare da un tale strumento? La risposta +dipende dal linguaggio su cui si effettua il debug, comunque in generale ci si +pu@`o attendere almeno questo: + +@itemize @value{BULLET} +@item +La possibilit@`a di osservare l'esecuzione delle istruzioni di un programma una +per una, dando al programmatore l'opportunit@`a di pensare a quel che accade a +una scala temporale di secondi, minuti od ore, piuttosto che alla scala dei +nanosecondi alla quale normalmente viene eseguito il codice. + +@item +L'opportunit@`a, non solo di osservare passivamente le operazioni del progamma, +ma di controllarlo e tentare diversi percorsi di esecuzione, senza dover +modificare i file sorgenti. + +@item +La possibilit@`a di vedere i valori o i dati nel programma in qualsiasi punto +dell'esecuzione, e anche di cambiare i dati al volo, per vedere come questo +influisca su ci@`o che accade dopo. (Questo include spesso la capacit@`a di +esaminare le strutture interne dei dati oltre alle variabili che +sono state effettivamente definite nel codice del programma.) + +@item +La possibilit@`a di ottenere ulteriori informazioni sullo stato del programma +o anche sulle sue strutture interne. +@end itemize + +Tutti questi strumenti sono di grande aiuto e permettono di usare l'abilit@`a +che si possiede e la comprensione che si ha degli obiettivi del programma +per trovare dove si verificano i problemi (o, in alternativa, per +comprendere meglio la logica di un programma funzionante, di cui si sia +l'autore, o anche di un programma scritto da altri). + +@node Terminologia nel debug +@subsection Concetti fondamentali sul debug + +Prima di entrare nei dettagli, dobbiamo introdurre diversi +importanti concetti che valgono per tutti i debugger. +La seguente lista definisce i termini usati nel resto di +questo @value{CHAPTER}: + +@table @dfn +@cindex @dfn{stack frame} +@item Stack frame +Durante la loro esecuzione i programmi normalmente chiamano delle funzioni. +Una funzione pu@`o a sua volta chiamarne un'altra, o pu@`o richiamare se stessa +(ricorsione). La +catena di funzioni chiamate (il programma principale chiama A, che chiama B, +che chiama C) pu@`o essere vista come una pila di funzioni in esecuzione: la +funzione correntemente in esecuzione @`e quella in cima alla pila, e quando +questa finisce (ritorna al chiamante), +quella immediatamente sotto diventa la funzione +attiva. Tale pila (@dfn{stack}) @`e chiamata @dfn{call stack} (pila delle chiamate). + +Per ciascuna funzione della pila delle chiamate (@dfn{call stack}), il sistema +mantiene un'area di dati che contiene i parametri della funzione, le variabili +locali e i valori di ritorno, e anche ogni altra informazione ``contabile'' +necessaria per gestire la pila delle chiamate. Quest'area di dati @`e chiamata +@dfn{stack frame}. + +Anche @command{gawk} segue questo modello, e permette l'accesso alla pila +delle chiamate e a ogni @dfn{stack frame}. @`E possibile esaminare la pila +delle chiamate, e anche sapere da dove ciascuna funzione sulla pila @`e stata +invocata. I comandi che stampano la pila delle chiamate stampano anche le +informazioni su ogni @dfn{stack frame} (come vedremo pi@`u avanti in dettaglio). + +@item Punto d'interruzione +@cindex breakpoint +@cindex punto d'interruzione +Durante le operazioni di debug, spesso si preferisce lasciare che il programma +venga eseguito finch@'e non raggiunge un certo punto, e da quel punto in poi si +continua l'esecuzione un'istruzione alla volta. Il modo per farlo @`e quello di +impostare un @dfn{punto d'interruzione} all'interno del programma. Un punto +d'interruzione @`e il punto dove l'esecuzione del programma dovrebbe +interrompersi (fermarsi), in modo da assumere il controllo dell'esecuzione del +programma. Si possono aggiungere e togliere quanti punti d'interruzione si +vogliono. + +@item Punto d'osservazione +@cindex @dfn{watchpoint} +@cindex punto d'osservazione +Un punto d'osservazione @`e simile a un punto d'interruzione. La differenza @`e +che i punti d'interruzione sono orientati attorno al codice; fermano il +programma quando viene raggiunto un certo punto nel codice. Un punto +d'osservazione, invece, fa fermare il programma quando @`e stato +cambiato il @emph{valore di un dato}. Questo @`e utile, poich@'e a volte succede +che una variabile riceva un valore errato, ed @`e difficile rintracciare il punto +dove ci@`o accade solo leggendo il codice sorgente. +Usando un punto d'osservazione, si pu@`o fermare il programma in qualunque punto +vi sia un'assegnazione di variabile, e di solito si individua il codice che +genera l'errore abbastanza velocemente. +@end table + +@node Debug di Awk +@subsection Il debug di @command{awk} + +Il debug di un programma @command{awk} ha delle particolarit@`a proprie, che +non sono presenti in programmi scritti in altri linguaggi. + +Prima di tutto, il fatto che i programmi @command{awk} ricevano generalmente +l'input riga per riga da uno o pi@`u file e operino su tali righe usando regole +specifiche, rende particolarmente agevole organizzare l'esame +dell'esecuzione del programma facendo riferimento a tali regole. +Come vedremo, ogni +regola @command{awk} viene trattata quasi come una chiamata di funzione, col +proprio specifico blocco di istruzioni. + +Inoltre, poich@'e @command{awk} @`e un linguaggio deliberatamente molto +conciso, @`e facile perdere di vista tutto ci@`o che avviene ``dentro'' +ogni riga di codice @command{awk}. Il debugger d@`a l'opportunit@`a di +guardare le singole istruzioni primitive la cui esecuzione @`e innescata +dai comandi di alto livello di @command{awk}. + +@node Esempio di sessione di debug +@section Esempio di sessione di debug di @command{gawk} +@cindex esempio di sessione di debug +@cindex debug, esempio di sessione + +Per illustrare l'uso di @command{gawk} come debugger, vediamo un esempio di +sessione di debug. Come esempio verr@`a usata l'implementazione @command{awk} +del comando POSIX @command{uniq} descritta in precedenza (@pxref{Programma +uniq}). + +@menu +* Invocazione del debugger:: Come far partire il debugger. +* Trovare il bug:: Trovare il bug. +@end menu + +@node Invocazione del debugger +@subsection Come avviare il debugger +@cindex avviare il debugger +@cindex debugger, come avviarlo +@cindex debugger, comandi del, si veda comando del debugger + +Per avviare il debugger in @command{gawk} si richiama il comando esattamente +come al solito, specificando solo un'opzione aggiuntiva, +@option{--debug}, o la corrispondente opzione breve @option{-D}. +I file (o il file) che contengono +il programma e ogni codice ulteriore sono immessi sulla riga di comando come +argomenti a una o pi@`u opzioni @option{-f}. (@command{gawk} non @`e progettato per +eseguire il debug di programmi scritti sulla riga di comando, ma solo per +quello di programmi che risiedono su file.) +Nel nostro caso, il debugger verr@`a invocato in questo modo: + +@example +$ @kbd{gawk -D -f getopt.awk -f join.awk -f uniq.awk -1 file_di_input} +@end example + +@noindent +dove entrambi i file @file{getopt.awk} e @file{uniq.awk} sono in @env{$AWKPATH}. +(Gli utenti esperti di GDB o debugger simili dovrebbero tener presente che +questa sintassi @`e leggermente differente da quello che sono abituati a usare. +Col debugger di @command{gawk}, si danno gli argomenti per eseguire il +programma nella riga di comando al debugger piuttosto che come parte del +comando @code{run} al prompt del debugger.) +L'opzione @option{-1} @`e un'opzione per @file{uniq.awk}. + +Invece di eseguire direttamente il programma sul @file{file_di_input}, come +@command{gawk} farebbe normalmente, il debugger semplicemente carica +i file sorgenti del programma, li compila internamente, e poi mostra +la riga d'invito: + +@example +gawk> +@end example + +@noindent +da dove si possono impartire i comandi al debugger. Sin qui non @`e +stato ancora eseguito nessun codice. + +@node Trovare il bug +@subsection Trovare il bug + +Poniamo di avere un problema usando (una versione difettosa di) +@file{uniq.awk} nella modalit@`a ``salta-campi'', perch@'e sembra che non +catturi le righe che dovrebbero essere identiche dopo aver saltato il primo +campo, come: + +@example +awk, ecco un programma meraviglioso! +gawk, ecco un programma meraviglioso! +@end example + +Questo potrebbe accadere se noi pensassimo (come in C) che i campi in un record +siano numerati prendendo come base lo zero, per cui, invece di scrivere: + +@example +campi_ultima = join(vettore_ultima, contatore_file+1, n) +campi_corrente = join(vettore_corrente, contatore_file+1, m) +@end example + +@noindent +abbiamo scritto: + +@example +campi_ultima = join(vettore_ultima, contatore_file, n) +campi_corrente = join(vettore_corrente, contatore_file, m) +@end example + +La prima cosa da fare quando si tenta di indagare su un problema come questo @`e +quella di mettere un punto d'interruzione (@dfn{breakpoint}) nel programma, in modo +da poterlo vedere al lavoro e catturare quello che non va. Una posizione +ragionevole per un punto d'interruzione in @file{uniq.awk} @`e all'inizio della +funzione @code{se_sono_uguali()}, che confronta la riga corrente con la precedente. +Per impostare il punto d'interruzione, usare il comando @code{b} (@dfn{breakpoint}): + +@example +gawk> @kbd{b se_sono_uguali} +@print{} Breakpoint 1 impostato al file `uniq.awk', riga 63 +@end example + +Il debugger mostra il file e il numero di riga dove si trova il punto +d'interruzione. Ora bisogna immettere @samp{r} o @samp{run} e il programma +viene eseguito fino al primo punto d'interruzione: + +@example +gawk> @kbd{r} +@print{} Partenza del programma: +@print{} Mi fermo in Rule ... +@print{} Breakpoint 1, se_sono_uguali(n, m, campi_ultima, campi_corrente, +@print{} vettore_ultima, vettore_corrente) +@print{} a `uniq.awk':63 +@print{} 63 if (contatore_file == 0 && conta_caratteri == 0) +gawk> +@end example + +Ora possiamo osservare cosa accade all'interno del nostro programma. +Prima di tutto, vediamo come siamo arrivati a questo punto. Sulla riga di +comando battiamo @samp{bt} (che sta per ``backtrace''), e il debugger risponde +con un listato degli @dfn{stack frame} correnti: + +@example +gawk> @kbd{bt} +@print{} #0 se_sono_uguali(n, m, campi_ultima, campi_corrente, +@print{} vettore_ultima, vettore_corrente) +@print{} a `uniq.awk':63 +@print{} #1 in main() a `uniq.awk':88 +@end example + +Questo ci dice che la funzione @code{se_sono_uguali()} @`e stata chiamata +dal programma principale alla riga 88 del file @file{uniq.awk}. (Questo non +sorprende, perch@'e @`e questa l'unica chiamata a @code{se_sono_uguali()} nel +programma, per@`o in programmi +pi@`u complessi, sapere chi ha chiamato una funzione e con quali parametri pu@`o +essere la chiave per trovare l'origine del problema.) + +Ora che siamo in @code{se_sono_uguali()}, possiamo iniziare a guardare i valori di +alcune variabili. Immaginiamo di battere @samp{p n} +(@code{p} sta per @dfn{print} [stampa]). Ci aspetteremo di vedere il valore di +@code{n}, un parametro di @code{se_sono_uguali()}. In realt@`a, il debugger +ci d@`a: + +@example +gawk> @kbd{p n} +@print{} n = untyped variable +@end example + +@noindent +In questo caso, @code{n} @`e una variabile locale non inizializzata, perch@'e la +funzione @`e stata chiamata senza argomenti (@pxref{Chiamate di funzione}). + +Una variabile pi@`u utile da visualizzare potrebbe essere la seguente: + +@example +gawk> @kbd{p $0} +@print{} $0 = "gawk, ecco un programma meraviglioso!" +@end example + +@noindent +All'inizio questo potrebbe lasciare un tantino perplessi, perch@'e @`e la seconda +riga dell'input del test. Vediamo @code{NR}: + +@example +gawk> @kbd{p NR} +@print{} NR = 2 +@end example + +@noindent +Come si pu@`o vedere, @code{se_sono_uguali()} @`e stata chiamata solo per la seconda +riga del file. Naturalmente, ci@`o accade perch@'e il nostro programma contiene +una regola per @samp{NR == 1}: + +@example +NR == 1 @{ + ultima = $0 + next +@} +@end example + +Bene, controlliamo che questa funzioni correttamente: + +@example +gawk> @kbd{p ultima} +@print{} ultima = "awk, ecco un programma meraviglioso!" +@end example + +Tutto ci@`o che @`e stato fatto fin qui ha verificato che il programma funziona +come previsto fino alla chiamata a @code{se_sono_uguali()} compresa; quindi +il problema dev'essere all'interno di questa funzione. Per indagare +ulteriormente, iniziamo a ``scorrere una ad una'' le righe di +@code{se_sono_uguali()}. Cominciamo col battere @samp{n} (per ``next'' +[successivo]): + +@example +gawk> @kbd{n} +@print{} 66 if (contatore_file > 0) @{ +@end example + +Questo ci dice che @command{gawk} ora @`e pronto per eseguire la riga 66, che +decide se assegnare alle righe il trattamento speciale ``salta-campi'' +indicato dall'opzione sulla riga di comando @option{-1}. (Si noti che abbiamo +saltato da dov'eravamo prima, alla riga 63, a qui, perch@'e la condizione nella +riga 63, @samp{if (contatore_file == 0 && conta_caratteri == 0)}, era falsa.) + +Continuando a scorrere le righe, ora raggiungiamo la divisione del record +corrente e dell'ultimo: + +@example +gawk> @kbd{n} +@print{} 67 n = split(ultima, vettore_ultima) +gawk> @kbd{n} +@print{} 68 m = split($0, vettore_corrente) +@end example + +A questo punto, potremmo stare a vedere in quante parti il nostro record +@`e stato suddiviso, quindi proviamo a osservare: + +@example +gawk> @kbd{p n m vettore_ultima vettore_corrente} +@print{} n = 5 +@print{} m = untyped variable +@print{} vettore_ultima = array, 5 elements +@print{} vettore_corrente = untyped variable +@end example + +@noindent +(Il comando @code{p} pu@`o accettare pi@`u argomenti, analogamente +all'istruzione di @command{awk} @code{print}.) + +Questo ci lascia piuttosto perplessi. Tutto ci@`o che abbiamo trovato @`e che ci +sono cinque elementi in @code{vettore_ultima}; @code{m} e @code{vettore_corrente} non hanno valori +perch@'e siamo alla riga 68 che non @`e ancora stata eseguita. Questa +informazione @`e abbastanza utile (ora sappiamo che nessuna delle parole @`e stata +lasciata fuori accidentalmente), ma sarebbe desiderabile vedere i valori +del vettore. + +Una prima possibilit@`a @`e quella di usare degli indici: + +@example +gawk> @kbd{p vettore_ultima[0]} +@print{} "0" non presente nel vettore `vettore_ultima' +@end example + +@noindent +Oops! + +@example +gawk> @kbd{p vettore_ultima[1]} +@print{} vettore_ultima["1"] = "awk," +@end example + +Questo metodo sarebbe piuttosto lento per un vettore con 100 elementi, per cui +@command{gawk} fornisce una scorciatoia (che fa venire in mente un altro +linguaggio che non nominiamo): + +@example +gawk> @kbd{p @@vettore_ultima} +@print{} vettore_ultima["1"] = "awk," +@print{} vettore_ultima["2"] = "ecco" +@print{} vettore_ultima["3"] = "un" +@print{} vettore_ultima["4"] = "programma" +@print{} vettore_ultima["5"] = "meraviglioso!" +@end example + +Finora, sembra che tutto vada bene. Facciamo un altro passo, +o anche due: + +@example +gawk> @kbd{n} +@print{} 69 campi_ultima = join(vettore_ultima, contatore_file, n) +gawk> @kbd{n} +@print{} 70 campi_corrente = join(vettore_corrente, contatore_file, m) +@end example + +Bene, eccoci arrivati al nostro errore (ci spiace di aver rovinato la +sorpresa). +Quel che avevamo in mente era di unire i campi a partire dal secondo per +creare il record virtuale da confrontare, e se il primo campo aveva il numero +zero, questo avrebbe funzionato. Vediamo quel che abbiamo finora: + +@example +gawk> @kbd{p campi_ultima campi_corrente} +@print{} campi_ultima = "awk, ecco un programma meraviglioso!" +@print{} campi_corrente = "gawk, ecco un programma meraviglioso!" +@end example + +Ehi! queste frasi suonano piuttosto familiari! Sono esattamente i nostri +record di input originali, inalterati. Pensandoci un po' (il cervello umano @`e +ancora il miglior strumento di debug), ci si rende conto che eravamo fuori di +uno! + +Usciamo dal debugger: + +@example +gawk> @kbd{q} +@print{} Il programma @`e in esecuzione. Esco comunque (y/n)? @kbd{y} +@end example + +@noindent +Quindi modifichiamo con un editore di testo: + +@example +campi_ultima = join(vettore_ultima, contatore_file+1, n) +campi_corrente = join(vettore_corrente, contatore_file+1, m) +@end example + +@noindent +e il problema @`e risolto! + +@node Lista dei comandi di debug +@section I principali comandi di debug + +L'insieme dei comandi del debugger di @command{gawk} pu@`o essere diviso nelle +seguenti categorie: + +@itemize @value{BULLET} + +@item +Controllo di punti d'interruzione + +@item +Controllo di esecuzione + +@item +Vedere e modificare dati + +@item +Lavorare con le pile + +@item +Ottenere informazioni + +@item +Comandi vari +@end itemize + +Ciascuna di esse @`e trattata nelle sottosezioni che seguono. +Nelle descrizioni seguenti, i comandi che possono essere abbreviati +mostrano l'abbreviazione su una seconda riga di descrizione. +Un nome di comando del debugger pu@`o essere anche troncato se la parte gi@`a scritta +non @`e ambigua. Il debugger ha la capacit@`a predefinita di ripetere +automaticamente il precedente comando semplicemente battendo @kbd{Invio}. +Questo vale per i comandi @code{list}, @code{next}, @code{nexti}, +@code{step}, @code{stepi} e @code{continue} quando sono eseguiti senza +argomenti. + +@menu +* Controllo dei breakpoint:: Controllo dei punti d'interruzione. +* Controllo esecuzione debugger:: Controllo di esecuzione. +* Vedere e modificare dati:: Vedere e modificare dati. +* Stack di esecuzione:: Lavorare con le pile. +* Informazioni sul debugger:: Ottenere informazioni sullo stato del + programma e del debugger. +* Comandi vari del debugger:: Comandi vari del debugger. +@end menu + +@node Controllo dei breakpoint +@subsection Controllo dei punti d'interruzione + +Come abbiamo gi@`a visto, la prima cosa che si dovrebbe fare in una sessione di +debug @`e quella di definire dei punti d'interruzione, poich@'e altrimenti il +programma verr@`a eseguito come se non fosse sotto il debugger. I comandi per +controllare i punti d'interruzione sono: + +@table @asis +@cindex comando del debugger, @code{b} (alias per @code{break}) +@cindex comando del debugger, @code{break} +@cindex @code{break}, comando del debugger +@cindex @code{b}, comando del debugger (alias per @code{break}) +@cindex impostare un punto d'interruzione +@cindex breakpoint, impostare +@cindex punto d'interruzione (breakpoint), impostare +@item @code{break} [[@var{nome-file}@code{:}]@var{n} | @var{funzione}] [@code{"@var{espressione}"}] +@itemx @code{b} [[@var{nome-file}@code{:}]@var{n} | @var{funzione}] [@code{"@var{espressione}"}] +Senza argomenti, imposta un punto d'interruzione alla prossima istruzione +da eseguire nello @dfn{stack frame} selezionato. +Gli argomenti possono essere uno dei seguenti: + +@c @asis for docbook +@c nested table +@table @asis +@item @var{n} +Imposta un punto d'interruzione alla riga numero @var{n} nel file sorgente +corrente. + +@item @var{nome-file}@code{:}@var{n} +Imposta un punto d'interruzione alla riga numero @var{n} nel file sorgente +@var{nome-file}. + +@item @var{funzione} +Imposta un punto d'interruzione all'ingresso (la prima istruzione eseguibile) +della funzione @var{funzione}. +@end table + +A ogni punto d'interruzione @`e assegnato un numero che pu@`o essere usato per +cancellarlo dalla lista dei punti d'interruzione usando il comando +@code{delete}. + +Specificando un punto d'interruzione, si pu@`o fornire anche una condizione. +Questa @`e +un'espressione @command{awk} (racchiusa tra doppi apici) che il debugger +valuta ogni volta che viene raggiunto quel punto d'interruzione. Se la +condizione @`e vera, il debugger ferma l'esecuzione e rimane in attesa di un +comando. Altrimenti, continua l'esecuzione del programma. + +@cindex comando del debugger, @code{clear} +@cindex @code{clear}, comando del debugger +@cindex cancellare punto d'interruzione da una determinata posizione +@cindex punto d'interruzione in una determinata posizione, come cancellare +@cindex breakpoint, come cancellare +@item @code{clear} [[@var{nome-file}@code{:}]@var{n} | @var{funzione}] +Senza argomenti, cancella ogni eventuale punto d'interruzione all'istruzione +successiva +da eseguirsi nello @dfn{stack frame} selezionato. Se il programma si ferma in +un punto d'interruzione, quel punto d'interruzione viene cancellato in modo +che il programma non si fermi pi@`u in quel punto. +Gli argomenti possono essere uno tra i seguenti: + +@c nested table +@table @asis +@item @var{n} +Cancella il punto (o i punti) d'interruzione impostato/i alla riga @var{n} nel +file sorgente corrente. + +@item @var{nome-file}@code{:}@var{n} +Cancella il punto (o i punti) d'interruzione impostato/i alla riga @var{n} nel +file sorgente @var{nome-file}. + +@item @var{funzione} +Cancella il punto (o i punti) d'interruzione impostato/i all'ingresso della +funzione @var{funzione}. +@end table + +@cindex comando del debugger, @code{condition} +@cindex @code{condition}, comando del debugger +@cindex condizione dei punti d'interruzione +@item @code{condition} @var{n} @code{"@var{espressione}"} +Aggiunge una condizione al punto d'interruzione o al punto d'osservazione +esistente @var{n}. La condizione @`e un'espressione @command{awk} +@emph{racchiusa tra doppi apici} che il debugger valuta ogni volta che viene +raggiunto il punto d'interruzione o il punto d'osservazione. Se la condizione @`e +vera, il debugger ferma l'esecuzione e attende l'immissione di un comando. +Altrimenti, il debugger continua l'esecuzione del programma. Se l'espressione +della condizione non viene specificata, tutte le condizioni esistenti vengono +rimosse (cio@`e, il punto d'interruzione o di osservazione viene considerato +incondizionato). + +@cindex comando del debugger, @code{d} (alias per @code{delete}) +@cindex comando del debugger, @code{delete} +@cindex @code{delete}, comando del debugger +@cindex @code{d}, comando del debugger (alias per @code{delete}) +@cindex cancellare punto d'interruzione per numero +@cindex punto d'interruzione, cancellare per numero +@item @code{delete} [@var{n1 n2} @dots{}] [@var{n}--@var{m}] +@itemx @code{d} [@var{n1 n2} @dots{}] [@var{n}--@var{m}] +Cancella i punti d'interruzione specificati o un intervallo di punti +d'interruzione. Se non vengono forniti argomenti, cancella tutti i +punti d'interruzione esistenti. + +@cindex comando del debugger, @code{disable} +@cindex @code{disable}, comando del debugger +@cindex disabilitare punto d'interruzione +@cindex punto d'interruzione, come disabilitare o abilitare +@item @code{disable} [@var{n1 n2} @dots{} | @var{n}--@var{m}] +Disabilita punti d'interruzione specificati o un intervallo di essi. Senza +argomenti, disabilita tutti i punti d'interruzione. + +@cindex comando del debugger, @code{e} (alias per @code{enable}) +@cindex comando del debugger, @code{enable} +@cindex @code{enable}, comando del debugger +@cindex @code{e}, comando del debugger (alias per @code{enable}) +@cindex abilitare un punto d'interruzione +@item @code{enable} [@code{del} | @code{once}] [@var{n1 n2} @dots{}] [@var{n}--@var{m}] +@itemx @code{e} [@code{del} | @code{once}] [@var{n1 n2} @dots{}] [@var{n}--@var{m}] +Abilita specifici punti d'interruzione o un intervallo di essi. Senza +argomenti, abilita tutti i punti d'interruzione. +Opzionalmente, si pu@`o specificare come abilitare i punti d'interruzione: + +@c nested table +@table @code +@item del +Abilita dei punti d'interruzione @dfn{una tantum}, poi li cancella quando il +programma si ferma in quel punto. + +@item once +Abilita dei punti d'interruzione @dfn{una tantum}, poi li cancella quando il +programma si ferma in quel punto. +@end table + +@cindex comando del debugger, @code{ignore} +@cindex @code{ignore}, comando del debugger +@cindex ignorare un punto d'interruzione +@item @code{ignore} @var{n} @var{contatore} +Ignora il punto d'interruzione numero @var{n} le successive +@var{contatore} volte in cui viene raggiunto. + +@cindex comando del debugger, @code{t} (alias per @code{tbreak}) +@cindex comando del debugger, @code{tbreak} +@cindex @code{tbreak}, comando del debugger +@cindex @code{t}, comando del debugger (alias per @code{tbreak}) +@cindex punto d'interruzione temporaneo +@cindex temporaneo, punto d'interruzione +@item @code{tbreak} [[@var{nome-file}@code{:}]@var{n} | @var{funzione}] +@itemx @code{t} [[@var{nome-file}@code{:}]@var{n} | @var{funzione}] +Imposta un punto d'interruzione temporaneo (abilitato solo per la prima volta +che viene raggiunto). Gli argomenti sono gli stessi di @code{break}. +@end table + +@node Controllo esecuzione debugger +@subsection Controllo di esecuzione + +Dopo che i punti d'interruzione sono pronti, si pu@`o iniziare l'esecuzione del +programma, osservando il suo comportamento. Ci sono pi@`u comandi per +controllare l'esecuzione del programma di quelli visti nei precedenti esempi: + +@table @asis +@cindex comando del debugger, @code{commands} +@cindex @code{commands}, comando del debugger +@cindex comando del debugger, @code{silent} +@cindex @code{silent}, comando del debugger +@cindex comando del debugger, @code{end} +@cindex @code{end}, comando del debugger +@cindex punto d'interruzione, comandi +@cindex comandi da eseguire al punto d'interruzione +@item @code{commands} [@var{n}] +@itemx @code{silent} +@itemx @dots{} +@itemx @code{end} +Imposta una lista di comandi da eseguire subito dopo l'arresto del programma in +un punto d'interruzione o di osservazione. @var{n} @`e il numero del punto +d'interruzione o di osservazione. Se non si specifica un numero, viene usato +l'ultimo numero che @`e stato specificato. I comandi veri e propri seguono, +a cominciare dalla riga successiva, e hanno termine col comando @code{end}. +Se il comando @code{silent} @`e nella lista, i consueti messaggi sull'arresto del +programma a un punto d'interruzione e la riga sorgente non vengono stampati. +Qualsiasi comando nella lista che riprende l'esecuzione (p.es., +@code{continue}) pone fine alla lista (un @code{end} implicito), e i comandi +successivi vengono ignorati. +Per esempio: + +@example +gawk> @kbd{commands} +> @kbd{silent} +> @kbd{printf "Un punto d'interruzione silenzioso; i = %d\n", i} +> @kbd{info locals} +> @kbd{set i = 10} +> @kbd{continue} +> @kbd{end} +gawk> +@end example + +@cindex comando del debugger, @code{c} (alias per @code{continue}) +@cindex comando del debugger, @code{continue} +@cindex @code{continue}, comando del debugger +@item @code{continue} [@var{contatore}] +@itemx @code{c} [@var{contatore}] +Riprende l'esecuzione del programma. Se si riparte da un punto d'interruzione +e viene specificato @var{contatore}, il punto d'interruzione in quella +posizione viene ignorato per le prossime @var{contatore} volte prima di +fermarsi nuovamente. + +@cindex comando del debugger, @code{finish} +@cindex @code{finish}, comando del debugger +@item @code{finish} +Esegue fino a quando lo stack frame selezionato completa l'esecuzione. +Stampa il valore restituito. + +@cindex comando del debugger, @code{n} (alias per @code{next}) +@cindex comando del debugger, @code{next} +@cindex @code{next}, comando del debugger +@cindex @code{n}, comando del debugger (alias per @code{next}) +@cindex esecuzione di un solo passo, nel debugger +@item @code{next} [@var{contatore}] +@itemx @code{n} [@var{contatore}] +Continua l'esecuzione alla successiva riga sorgente, saltando le chiamate di +funzione. L'argomento @var{contatore} controlla il numero di ripetizioni +dell'azione, come in @code{step}. + +@cindex comando del debugger, @code{ni} (alias per @code{nexti}) +@cindex comando del debugger, @code{nexti} +@cindex @code{nexti}, comando del debugger +@cindex @code{ni}, comando del debugger (alias for @code{nexti}) +@item @code{nexti} [@var{contatore}] +@itemx @code{ni} [@var{contatore}] +Esegue una o @var{contatore} istruzioni, comprese le chiamate di funzione. + +@cindex comando del debugger, @code{return} +@cindex @code{return}, comando del debugger +@item @code{return} [@var{valore}] +Cancella l'esecuzione di una chiamata di funzione. Se @var{valore} (una +stringa o un numero) viene specificato, @`e usato come valore di ritorno della +funzione. Se usato in un frame diverso da quello pi@`u interno (la funzione +correntemente in esecuzione; cio@`e, il frame numero 0), ignora tutti i frame +pi@`u interni di quello selezionato, e il chiamante del frame selezionato +diventa il frame pi@`u interno. + +@cindex comando del debugger, @code{r} (alias per @code{run}) +@cindex comando del debugger, @code{run} +@cindex @code{run}, comando del debugger +@cindex @code{r}, comando del debugger (alias per @code{run}) +@item @code{run} +@itemx @code{r} +Avvia/riavvia l'esecuzione del programma. Quando il programma viene riavviato, +il debugger mantiene i punti d'interruzione e di osservazione, la cronologia +dei comandi, la visualizzazione automatica di variabili, e le opzioni del +debugger. + +@cindex comando del debugger, @code{s} (alias per @code{step}) +@cindex comando del debugger, @code{step} +@cindex @code{step}, comando del debugger +@cindex @code{s}, comando del debugger (alias per @code{step}) +@item @code{step} [@var{contatore}] +@itemx @code{s} [@var{contatore}] +Continua l'esecuzione finch@'e il controllo non raggiunge una diversa riga del +sorgente nello @dfn{stack frame} corrente, eseguendo ogni funzione chiamata +all'interno della riga. Se viene fornito l'argomento @var{contatore}, +esegue il numero di istruzioni specificate prima di fermarsi, a meno che non +s'imbatta in un punto d'interruzione o di osservazione. + +@cindex comando del debugger, @code{si} (alias per @code{stepi}) +@cindex comando del debugger, @code{stepi} +@cindex @code{stepi}, comando del debugger +@cindex @code{si}, comando del debugger (alias per @code{stepi}) +@item @code{stepi} [@var{contatore}] +@itemx @code{si} [@var{contatore}] +Esegue una o @var{contatore} istruzioni, comprese le chiamate di funzione. +(Per una spiegazione su cosa s'intende per ``istruzione'' in @command{gawk}, +si veda l'output mostrato sotto @code{dump} nella +@ref{Comandi vari del debugger}.) + +@cindex comando del debugger, @code{u} (alias per @code{until}) +@cindex comando del debugger, @code{until} +@cindex @code{until}, comando del debugger +@cindex @code{u}, comando del debugger (alias per @code{until}) +@item @code{until} [[@var{nome-file}@code{:}]@var{n} | @var{funzione}] +@itemx @code{u} [[@var{nome-file}@code{:}]@var{n} | @var{funzione}] +Senza argomenti, prosegue l'esecuzione finch@'e non viene raggiunta una riga +dopo la riga corrente nello @dfn{stack frame} corrente. +Se viene specificato un argomento, +prosegue l'esecuzione finch@'e non viene raggiunto il punto specificato, o +lo @dfn{stack frame} corrente non termina l'esecuzione. +@end table + +@node Vedere e modificare dati +@subsection Vedere e modificare dati + +I comandi per vedere e modificare variabili all'interno di @command{gawk} sono: + +@table @asis +@cindex comando del debugger, @code{display} +@cindex @code{display}, comando del debugger +@item @code{display} [@var{var} | @code{$}@var{n}] +Aggiunge la variabile @var{var} (o il campo @code{$@var{n}}) alla lista di +visualizzazione. Il valore della variabile o del campo @`e visualizzato ogni +volta che il programma s'interrompe. +Ogni variabile aggiunta alla lista @`e identificata da un numero univoco: + +@example +gawk> @kbd{display x} +@print{} 10: x = 1 +@end example + +@noindent +La riga qui sopra mostra il numero di elemento assegnato, il nome della +variabile e il suo +valore corrente. Se la variabile di display fa riferimento a un parametro di +funzione, @`e cancellata silenziosamente dalla lista non appena l'esecuzione +raggiunge un contesto dove la variabile con quel nome non esiste pi@`u. +Senza argomenti, @code{display} mostra i valori correnti degli elementi della +lista. + +@cindex comando del debugger, @code{eval} +@cindex @code{eval}, comando del debugger +@cindex valutare espressioni, nel debugger +@item @code{eval "@var{istruzioni awk}"} +Valuta @var{istruzioni awk} nel contesto del programma in esecuzione. +Si pu@`o fare qualsiasi cosa che un programma @command{awk} farebbe: assegnare +valori a variabili, chiamare funzioni, e cos@`{@dotless{i}} via. + +@item @code{eval} @var{param}, @dots{} +@itemx @var{istruzioni awk} +@itemx @code{end} +Questa forma di @code{eval} @`e simile alla precedente, solo che permette di +definire +``variabili locali'' che esistono nel contesto delle @var{istruzioni awk}, +invece di usare variabili o parametri di funzione gi@`a definiti nel programma. + +@cindex comando del debugger, @code{p} (alias per @code{print}) +@cindex comando del debugger, @code{print} +@cindex @code{print}, comando del debugger +@cindex @code{p}, comando del debugger (alias per @code{print}) +@cindex stampare variabili, nel debugger +@item @code{print} @var{var1}[@code{,} @var{var2} @dots{}] +@itemx @code{p} @var{var1}[@code{,} @var{var2} @dots{}] +Stampa i valori di una o pi@`u variabili o campi di @command{gawk}. +I campi devono essere indicizzati usando delle costanti: + +@example +gawk> @kbd{print $3} +@end example + +@noindent +Questo stampa il terzo campo del record di input (se il campo specificato non +esiste, stampa il @samp{campo nullo}). Una variabile pu@`o essere un elemento di +un vettore, avente come indice una +stringa di valore costante. Per stampare +il contenuto di un vettore, si deve anteporre il simbolo @samp{@@} al nome del +vettore: + +@example +gawk> @kbd{print @@a} +@end example + +@noindent +L'esempio stampa gli indici e i corrispondenti valori di tutti gli elementi +del vettore @code{a}. + +@cindex comando del debugger, @code{printf} +@cindex @code{printf}, comando del debugger +@item @code{printf} @var{formato} [@code{,} @var{arg} @dots{}] +Stampa un testo formattato. Il @var{formato} pu@`o includere sequenze di +protezione, come @samp{\n} +(@pxref{Sequenze di protezione}). +Non viene stampato nessun ritorno a capo che non sia stato specificato +esplicitamente. + +@cindex comando del debugger, @code{set} +@cindex @code{set}, comando del debugger +@cindex assegnare valori a variabili, nel debugger +@item @code{set} @var{var}@code{=}@var{valore} +Assegna un valore costante (numero o stringa) a una variabile o a un campo di +@command{awk}. +I valori di stringa devono essere racchiusi tra doppi apici +(@code{"}@dots{}@code{"}). + +Si possono impostare anche delle variabili speciali di @command{awk}, come +@code{FS}, @code{NF}, @code{NR}, e cos@`{@dotless{i}} via. + +@cindex comando del debugger, @code{w} (alias per @code{watch}) +@cindex comando del debugger, @code{watch} +@cindex @code{watch}, comando del debugger +@cindex @code{w}, comando del debugger (alias per @code{watch}) +@cindex impostare un punto d'osservazione +@item @code{watch} @var{var} | @code{$}@var{n} [@code{"@var{espressione}"}] +@itemx @code{w} @var{var} | @code{$}@var{n} [@code{"@var{espressione}"}] +Aggiunge la variabile @var{var} (o il campo @code{$@var{n}}) alla lista dei +punti d'osservazione. Il debugger quindi interrompe il programma ogni volta +che il valore della variabile o del campo cambia. A ogni elemento osservato +viene assegnato un numero che pu@`o essere usato per cancellarlo dalla lista +usando il comando @code{unwatch} [non-osservare pi@`u]. + +Definendo un punto d'osservazione, si pu@`o anche porre una condizione, che @`e +un'espressione @command{awk} (racchiusa tra doppi apici) che il debugger valuta +ogni volta che viene raggiunto il punto d'osservazione. Se la condizione @`e +vera, il debugger interrompe l'esecuzione e rimane in attesa di un comando. +Altrimenti, @command{gawk} prosegue nell'esecuzione del programma. + +@cindex comando del debugger, @code{undisplay} +@cindex @code{undisplay}, comando del debugger +@cindex interruzione visualizzazioni automatiche, nel debugger +@item @code{undisplay} [@var{n}] +Rimuove l'elemento numero @var{n} (o tutti gli elementi, se non vi sono +argomenti) dalla lista delle visualizzazioni automatiche. + +@cindex comando del debugger, @code{unwatch} +@cindex @code{unwatch}, comando del debugger +@cindex cancellare punto d'osservazione +@item @code{unwatch} [@var{n}] +Rimuove l'elemento numero @var{n} (o tutti gli elementi, se non vi sono +argomenti) dalla lista dei punti d'osservazione. + +@end table + +@node Stack di esecuzione +@subsection Lavorare con lo stack + +Ogni volta che si esegue un programma che contiene chiamate di funzione, +@command{gawk} mantiene una pila contenente la lista delle chiamate di funzione +che hanno portato al punto in cui il programma si trova in ogni momento. @`E +possibile vedere a che punto si trova il programma, e anche muoversi +all'interno della pila per vedere qual era lo stato delle cose nelle funzioni +che hanno chiamato quella in cui ci si trova. I comandi per far questo sono: + +@table @asis +@cindex comando del debugger, @code{bt} (alias per @code{backtrace}) +@cindex comando del debugger, @code{backtrace} +@cindex comando del debugger, @code{where} (alias per @code{backtrace}) +@cindex @code{backtrace}, comando del debugger +@cindex @code{bt}, comando del debugger (alias per @code{backtrace}) +@cindex @code{where}, comando del debugger +@cindex @code{where}, comando del debugger (alias per @code{backtrace}) +@cindex chiamate, @dfn{stack} (pila) delle, mostrare nel debugger +@cindex @dfn{stack} (pila) delle chiamate, mostrare nel debugger +@cindex pila (@dfn{stack}) delle chiamate, mostrare nel debugger +@cindex tracciatura a ritroso, mostrare nel debugger +@item @code{backtrace} [@var{contatore}] +@itemx @code{bt} [@var{contatore}] +@itemx @code{where} [@var{contatore}] +Stampa a ritroso una traccia di tutte le chiamate di funzione (stack frame), o +i dei @var{contatore} frame pi@`u interni se @var{contatore} > 0. Stampa i +@var{contatore} frame pi@`u esterni se @var{contatore} < 0. La tracciatura a +ritroso mostra il nome e gli argomenti di ciascuna funzione, il sorgente +@value{FN}, e il numero di riga. L'alias @code{where} per @code{backtrace} +viene mantenuto per i vecchi utenti di GDB che potrebbero essere abituati a +quel comando. + +@cindex comando del debugger, @code{down} +@cindex @code{down}, comando del debugger +@item @code{down} [@var{contatore}] +Sposta @var{contatore} (default 1) frame sotto la pila verso il frame pi@`u interno. +Poi seleziona e stampa il frame. + +@cindex comando del debugger, @code{f} (alias per @code{frame}) +@cindex comando del debugger, @code{frame} +@cindex @code{frame}, comando del debugger +@cindex @code{f}, comando del debugger (alias per @code{frame}) +@item @code{frame} [@var{n}] +@itemx @code{f} [@var{n}] +Seleziona e stampa lo @dfn{stack frame} @var{n}. Il frame 0 @`e quello +correntemente in esecuzione, o il frame @dfn{pi@`u interno}, (chiamata di +funzione); il frame 1 @`e il frame che ha chiamato quello pi@`u interno. Il frame +col numero pi@`u alto @`e quello per il programma principale. Le informazioni +stampate comprendono il numero di frame, i nomi delle funzioni e degli +argomenti, i file sorgenti e le righe sorgenti. + +@cindex comando del debugger, @code{up} +@cindex @code{up}, comando del debugger +@item @code{up} [@var{contatore}] +Sposta @var{contatore} (default 1) frame sopra la pila verso il frame pi@`u +esterno. Poi seleziona e stampa il frame. +@end table + +@node Informazioni sul debugger +@subsection Ottenere informazioni sullo stato del programma e del debugger + +Oltre che vedere i valori delle variabili, spesso si ha necessit@`a di ottenere +informazioni di altro tipo sullo stato del programma e dello stesso ambiente di +debug. Il debugger di @command{gawk} ha un comando che fornisce +quest'informazione, chiamato convenientemente @code{info}. @code{info} +@`e usato con uno dei tanti argomenti che dicono esattamente quel che si vuol +sapere: + +@table @asis +@cindex comando del debugger, @code{i} (alias per @code{info}) +@cindex comando del debugger, @code{info} +@cindex @code{info}, comando del debugger +@cindex @code{i}, comando del debugger (alias per @code{info}) +@item @code{info} @var{cosa} +@itemx @code{i} @var{cosa} +Il valore di @var{cosa} dovrebbe essere uno dei seguenti: + +@c nested table +@table @code +@item args +@cindex mostrare argomenti delle funzioni, nel debugger +@cindex debugger, mostrare argomenti delle funzioni +Elenca gli argomenti del frame selezionato. + +@item break +@cindex mostrare punti d'interruzione, nel debugger +@cindex debugger, mostrare punti d'interruzione +Elenca tutti i punti d'interruzione attualmente impostati. + +@item display +@cindex visualizzazioni automatiche, nel debugger +@cindex debugger, visualizzazioni automatiche +Elenca tutti gli elementi della lista delle visualizzazioni automatiche. + +@item frame +@cindex descrizione degli @dfn{stack frame} delle chiamate, nel debugger +@cindex debugger, descrizione degli @dfn{stack frame} delle chiamate +D@`a una descrizione degli @dfn{stack frame} selezionati. + +@item functions +@cindex elencare definizioni delle funzioni, nel debugger +@cindex debugger, elencare definizioni delle funzioni +Elenca tutte le definizioni delle funzioni compresi i @value{FNS} e +i numeri di riga. + +@item locals +@cindex mostrare variabili locali, nel debugger +@cindex debugger, mostrare variabili locali +Elenca le variabili locali dei frame selezionati. + +@item source +@cindex mostrare il nome del file sorgente corrente, nel debugger +@cindex debugger, mostrare il nome del file sorgente corrente +Stampa il nome del file sorgente corrente. Ogni volta che il programma si +interrompe, il file sorgente corrente @`e il file che contiene l'istruzione +corrente. Quando il debugger viene avviato per la prima volta, il file +sorgente corrente @`e il primo file incluso attraverso l'opzione @option{-f}. +Il comando @samp{list @var{nome-file}:@var{numero-riga}} pu@`o essere usato in +qualsiasi momento per cambiare il sorgente corrente. + +@item sources +@cindex mostrare tutti i file sorgente, nel debugger +@cindex debugger, mostrare tutti i file sorgenti +Elenca tutti i sorgenti del programma. + +@item variables +@cindex elencare tutte le variabili locali, nel debugger +@cindex debugger, elencare tutte le variabili locali +Elenca tutte le variabili locali. + +@item watch +@cindex mostrare i punti d'osservazione, nel debugger +@cindex debugger, mostrare i punti d'osservazione +Elenca tutti gli elementi della lista dei punti d'osservazione. +@end table +@end table + +Ulteriori comandi permettono di avere il controllo sul debugger, la capacit@`a di +salvare lo stato del debugger e la capacit@`a di eseguire comandi del debugger +da un file. I comandi sono: + +@table @asis +@cindex comando del debugger, @code{o} (alias per @code{option}) +@cindex comando del debugger, @code{option} +@cindex @code{option}, comando del debugger +@cindex @code{o}, comando del debugger (alias per @code{option}) +@cindex visualizzare le opzioni del debugger +@cindex debugger, opzioni del +@item @code{option} [@var{nome}[@code{=}@var{valore}]] +@itemx @code{o} [@var{nome}[@code{=}@var{valore}]] +Senza argomenti, visualizza le opzioni del debugger disponibili e i loro valori +correnti. @samp{option @var{nome}} mostra il valore corrente dell'opzione +cos@`{@dotless{i}} denominata. @samp{option @var{nome}=@var{valore}} assegna +un nuovo valore all'opzione. +Le opzioni disponibili sono: + +@c nested table +@c asis for docbook +@table @asis +@item @code{history_size} +@cindex debugger, dimensione della cronologia +Imposta il numero massimo di righe da mantenere nel file della cronologia +@file{./.gawk_history}. Il valore di default @`e 100. + +@item @code{listsize} +@cindex debugger, numero di righe nella lista di default +Specifica il numero di righe che @code{list} deve stampare. Il valore di +default @`e 15. + +@item @code{outfile} +@cindex ridirezionare l'output di @command{gawk}, nel debugger +@cindex debugger, ridirezionare l'output di @command{gawk} +Invia l'output di @command{gawk} in un file; l'output del debugger @`e +visualizzato comunque anche +nello standard output. Assegnare come valore stringa vuota (@code{""}) +reimposta l'output solo allo standard output. + +@item @code{prompt} +@cindex debugger, prompt +Cambia la riga per l'immissione dei comandi del debugger. Il valore di +default @`e @samp{@w{gawk> }}. + +@item @code{save_history} [@code{on} | @code{off}] +@cindex debugger, file della cronologia +Salva la cronologia dei comandi nel file @file{./.gawk_history}. +L'impostazione di default @`e @code{on}. + +@item @code{save_options} [@code{on} | @code{off}] +@cindex salvataggio opzioni debugger +@cindex debugger, salvataggio opzioni +Salva le opzioni correnti nel file @file{./.gawkrc} all'uscita. +L'impostazione di default @`e @code{on}. +Le opzioni sono lette di nuovo all'avvio della sessione successiva. + +@item @code{trace} [@code{on} | @code{off}] +@cindex istruzioni, tener traccia delle, nel debugger +@cindex debugger, tener traccia delle istruzioni +Attiva o disattiva il tracciamento delle istruzioni. L'impostazione di default +@`e @code{off}. +@end table + +@item @code{save} @var{nome-file} +Salva i comandi eseguiti nella sessione corrente nel @value{FN} indicato, +in modo da poterli ripetere in seguito usando il comando @command{source}. + +@item @code{source} @var{nome-file} +@cindex debugger, leggere comandi da un file +Esegue comandi contenuti in un file; un errore in un comando non impedisce +l'esecuzione dei comandi successivi. In un file di comandi sono consentiti +i commenti (righe che iniziano con @samp{#}). +Le righe vuote vengono ignorate; esse @emph{non} +ripetono l'ultimo comando. +Non si pu@`o riavviare il programma mettendo pi@`u di un comando @code{run} +nel file. Inoltre, la lista dei comandi pu@`o includere altri comandi +@code{source}; in ogni caso, il debugger di @command{gawk} non richiama lo +stesso file pi@`u di una volta per evitare ricorsioni infinite. + +Oltre al comando @code{source}, o al posto di esso, si possono usare le opzioni +sulla riga di comando @option{-D @var{file}} o @option{--debug=@var{file}} +per eseguire comandi da un file in maniera non interattiva +(@pxref{Opzioni}). +@end table + +@node Comandi vari del debugger +@subsection Comandi vari del debugger + +Ci sono alcuni altri comandi che non rientrano nelle precedenti categorie, +come i seguenti: + +@table @asis +@cindex comando del debugger, @code{dump} +@cindex @code{dump}, comando del debugger +@item @code{dump} [@var{nome-file}] +Riversa il @dfn{byte code} del programma nello standard output o nel file +definito in @var{nome-file}. Questo stampa una rappresentazione delle +istruzioni interne che @command{gawk} esegue per implementare i comandi +@command{awk} in un programma. Ci@`o pu@`o essere molto istruttivo, come +dimostra il seguente riversamento parziale del codice offuscato di +Davide Brini (@pxref{Programma signature}): + +@c FIXME: This will need updating if num-handler branch is ever merged in. +@smallexample +gawk> @kbd{dump} +@print{} # BEGIN +@print{} +@print{} [ 1:0xfcd340] Op_rule : [in_rule = BEGIN] [source_file = brini.awk] +@print{} [ 1:0xfcc240] Op_push_i : "~" [MALLOC|STRING|STRCUR] +@print{} [ 1:0xfcc2a0] Op_push_i : "~" [MALLOC|STRING|STRCUR] +@print{} [ 1:0xfcc280] Op_match : +@print{} [ 1:0xfcc1e0] Op_store_var : O +@print{} [ 1:0xfcc2e0] Op_push_i : "==" [MALLOC|STRING|STRCUR] +@print{} [ 1:0xfcc340] Op_push_i : "==" [MALLOC|STRING|STRCUR] +@print{} [ 1:0xfcc320] Op_equal : +@print{} [ 1:0xfcc200] Op_store_var : o +@print{} [ 1:0xfcc380] Op_push : o +@print{} [ 1:0xfcc360] Op_plus_i : 0 [MALLOC|NUMCUR|NUMBER] +@print{} [ 1:0xfcc220] Op_push_lhs : o [do_reference = true] +@print{} [ 1:0xfcc300] Op_assign_plus : +@print{} [ :0xfcc2c0] Op_pop : +@print{} [ 1:0xfcc400] Op_push : O +@print{} [ 1:0xfcc420] Op_push_i : "" [MALLOC|STRING|STRCUR] +@print{} [ :0xfcc4a0] Op_no_op : +@print{} [ 1:0xfcc480] Op_push : O +@print{} [ :0xfcc4c0] Op_concat : [expr_count = 3] [concat_flag = 0] +@print{} [ 1:0xfcc3c0] Op_store_var : x +@print{} [ 1:0xfcc440] Op_push_lhs : X [do_reference = true] +@print{} [ 1:0xfcc3a0] Op_postincrement : +@print{} [ 1:0xfcc4e0] Op_push : x +@print{} [ 1:0xfcc540] Op_push : o +@print{} [ 1:0xfcc500] Op_plus : +@print{} [ 1:0xfcc580] Op_push : o +@print{} [ 1:0xfcc560] Op_plus : +@print{} [ 1:0xfcc460] Op_leq : +@print{} [ :0xfcc5c0] Op_jmp_false : [target_jmp = 0xfcc5e0] +@print{} [ 1:0xfcc600] Op_push_i : "%c" [MALLOC|STRING|STRCUR] +@print{} [ :0xfcc660] Op_no_op : +@print{} [ 1:0xfcc520] Op_assign_concat : c +@print{} [ :0xfcc620] Op_jmp : [target_jmp = 0xfcc440] +@print{} +@dots{} +@print{} +@print{} [ 2:0xfcc5a0] Op_K_printf : [expr_count = 17] [redir_type = ""] +@print{} [ :0xfcc140] Op_no_op : +@print{} [ :0xfcc1c0] Op_atexit : +@print{} [ :0xfcc640] Op_stop : +@print{} [ :0xfcc180] Op_no_op : +@print{} [ :0xfcd150] Op_after_beginfile : +@print{} [ :0xfcc160] Op_no_op : +@print{} [ :0xfcc1a0] Op_after_endfile : +gawk> +@end smallexample + +@cindex comando del debugger, @code{exit} +@cindex @code{exit}, comando del debugger +@cindex uscire dal debugger +@cindex debugger, uscire dal +@item @code{exit} +Esce dal debugger. +Si veda la voce @samp{quit}, pi@`u avanti in quest'elenco. + +@cindex comando del debugger, @code{h} (alias per @code{help}) +@cindex comando del debugger, @code{help} +@cindex @code{help}, comando del debugger +@cindex @code{h}, comando del debugger (alias per @code{help}) +@item @code{help} +@itemx @code{h} +Stampa una lista di tutti i comandi del debugger di @command{gawk} con un breve +sommario su come usarli. @samp{help @var{comando}} stampa l'informazione sul +comando @var{comando}. + +@cindex comando del debugger, @code{l} (alias per @code{list}) +@cindex comando del debugger, @code{list} +@cindex @code{list}, comando del debugger +@cindex @code{l}, comando del debugger (alias per @code{list}) +@item @code{list} [@code{-} | @code{+} | @var{n} | @var{nome-file}@code{:}@var{n} | @var{n}--@var{m} | @var{funzione}] +@itemx @code{l} [@code{-} | @code{+} | @var{n} | @var{nome-file}@code{:}@var{n} | @var{n}--@var{m} | @var{funzione}] +Stampa le righe specificate (per default 15) dal file sorgente corrente +o il file chiamato @var{nome-file}. I possibili argomenti di @code{list} +sono i seguenti: + +@c nested table +@table @asis +@item @code{-} (Meno) +Stampa righe prima delle ultime righe stampate. + +@item @code{+} +Stampa righe dopo le ultime righe stampate. +@code{list} senza argomenti fa la stessa cosa. + +@item @var{n} +Stampa righe centrate attorno alla riga numero @var{n}. + +@item @var{n}--@var{m} +Stampa righe dalla numero @var{n} alla numero @var{m}. + +@item @var{nome-file}@code{:}@var{n} +Stampa righe centrate attorno alla riga numero @var{n} nel file sorgente +@var{nome-file}. Questo comando pu@`o cambiare il file sorgente corrente. + +@item @var{funzione} +Stampa righe centrate attorno all'inizio della funzione @var{function}. +Questo comando pu@`o cambiare il file sorgente corrente. +@end table + +@cindex comando del debugger, @code{q} (alias per @code{quit}) +@cindex comando del debugger, @code{quit} +@cindex @code{quit}, comando del debugger +@cindex @code{q}, comando del debugger (alias per @code{quit}) +@cindex uscire dal debugger +@cindex debugger, uscire dal +@item @code{quit} +@itemx @code{q} +Esce dal debugger. Fare il debug @`e divertente, ma noi tutti a volte +dobbiamo far fronte ad altri impegni nella vita, e talvolta troviamo il bug +e possiamo tranquillamente passare a quello successivo! Come abbiamo visto +prima, se si sta eseguendo un programma, il debugger avverte quando si batte +@samp{q} o @samp{quit}, in modo da essere sicuri di voler realmente abbandonare +il debug. + +@cindex comando del debugger, @code{trace} +@cindex @code{trace}, comando del debugger +@item @code{trace} [@code{on} | @code{off}] +Abilita o disabilita la stampa continua delle istruzioni che si stanno per +eseguire, assieme alle righe di @command{awk} che implementano. +L'impostazione di default @`e @code{off}. + +@`E auspicabile che la maggior parte dei ``codici operativi'' (o ``opcode'') +in queste istruzioni siano sufficientemente autoesplicativi, e l'uso di +@code{stepi} e @code{nexti} mentre @code{trace} @`e abilitato li render@`a +familiari. + +@end table + +@node Supporto per Readline +@section Supporto per Readline +@cindex completamento dei comandi nel debugger +@cindex espansione della cronologia, nel debugger +@cindex debugger, completamento dei comandi nel + +Se @command{gawk} @`e compilato con +@uref{http://cnswww.cns.cwru.edu/php/chet/readline/readline.html, la libreria +GNU Readline}, ci si pu@`o avvantaggiare delle sue funzionalit@`a riguardanti il +completamento dei comandi della libreria e l'espansione della cronologia. Sono +disponibili i seguenti tipi di completamento: + +@table @asis +@item Completamentto dei comandi +Nomi dei comandi. + +@item Completamento del @value{FN} del sorgente +@value{FFNS} dei sorgenti. I relativi comandi sono +@code{break}, +@code{clear}, +@code{list}, +@code{tbreak} +e +@code{until}. + +@item Completamento di argomento +Argomenti di un comando non numerici. +I relativi comandi sono @code{enable} e @code{info}. + +@item Completamento del nome di variabile +Interessa i nomi delle variabili globali, e gli argomenti di funzione nel +contesto corrente se +il programma @`e in esecuzione. I relativi comandi sono +@code{display}, +@code{print}, +@code{set} +e +@code{watch}. + +@end table + +@node Limitazioni +@section Limitazioni + +Si spera che il lettore trovi il debugger di @command{gawk} utile e piacevole +da usare, ma come accade per ogni programma, specialmente nelle sue prime +versioni, ha ancora delle limitazioni. Quelle di cui @`e bene essere al corrente sono: + +@itemize @value{BULLET} +@item +Nella versione presente, il debugger non d@`a una spiegazione dettagliata +dell'errore che +si @`e commesso quando si immette qualcosa che il debugger ritiene sbagliato. +La risposta invece @`e solamente @samp{syntax error}. Quando si arriva a capire +l'errore commesso, tuttavia, ci si sentir@`a come un vero guru. + +@item +@c NOTE: no comma after the ref{} on purpose, due to following +@c parenthetical remark. +Se si studiano i ``dump'' dei codici operativi +@iftex +nella +@end iftex +@ifnottex +in +@end ifnottex +@ref{Comandi vari del debugger} +(o se si ha gi@`a familiarit@`a con i comandi interni di @command{gawk}), +ci si render@`a conto che gran parte della manipolaziona interna di dati +in @command{gawk}, cos@`{@dotless{i}} come in molti interpreti, @`e fatta su di una pila. +@code{Op_push}, @code{Op_pop}, e simili sono il pane quotidiano di +gran parte del codice di @command{gawk}. + +Sfortunatamente, al momento, il debugger di @command{gawk} non consente +di esaminare i contenuti della pila. +Cio@`e, i risultati intermedi della valutazione delle espressioni sono sulla +pila, ma non @`e possibile stamparli. Invece, possono essere stampate solo +quelle variabili che sono state definite nel programma. Naturalmente, un +espediente per cercare di rimediare @`e di usare pi@`u variabili esplicite in +fase di debug e +poi cambiarle di nuovo per ottenere un codice forse pi@`u difficile da +comprendere, ma pi@`u ottimizzato. + +@item +Non c'@`e alcun modo per guardare ``dentro'' al processo della compilazione delle +espressioni regolari per vedere se corrispondono a quel che si intendeva. +Come programmatore +di @command{awk}, ci si aspetta che chi legge conosca il significato di +@code{/[^[:alnum:][:blank:]]/}. + +@item +Il debugger di @command{gawk} @`e progettato per essere usato eseguendo un +programma (con tutti i suoi parametri) dalla riga di comando, come descritto +@iftex +nella +@end iftex +@ifnottex +in +@end ifnottex +@ref{Invocazione del debugger}. Non c'@`e alcun modo (al momento) di modificare +o di ``entrare dentro'' l'esecuzione di un programma. +Questo sembra ragionevole per un linguaggio che @`e usato principalmente per +eseguire programmi piccoli e che non richiedono molto tempo di esecuzione. + +@item +Il debugger di @command{gawk} accetta solo codice sorgente fornito con +l'opzione @option{-f}. +@end itemize + +@ignore +@c 11/2016: This no longer applies after all the type cleanup work that's been done. +C'@`e un altro punto che vale la pena di trattare. I debugger convenzionali +vengono eseguiti in un processo (e quindi in una parte di memoria) +separato dal programma su cui eseguono il debug (il @dfn{debuggato}, se +si vuole). + +Il debugger di @command{gawk} @`e diverso; @`e parte integrante di @command{gawk}. +Ci@`o rende possibile, in rari casi, che @command{gawk} diventi un eccellente +dimostratore del principio d'indeterminazione di Heisenberg, secondo il quale +il solo atto di osservare una cosa pu@`o modificarla. Si consideri il seguente +esempio:@footnote{Grazie a Hermann Peifer per quest'esempio.} + +@example +$ @kbd{cat test.awk} +@print{} @{ print typeof($1), typeof($2) @} +$ @kbd{cat test.data} +@print{} abc 123 +$ @kbd{gawk -f test.awk test.data} +@print{} strnum strnum +@end example + +Questo @`e quel che ci si aspetta: il campo data ha l'attributo STRNUM +(@pxref{Tipi di variabile}). Ora vediamo cosa accade quando questo programma +viene eseguito sotto il debugger: + +@example +$ @kbd{gawk -D -f test.awk test.data} +gawk> @kbd{w $1} @ii{Imposta un punto d'osservazione su} $1 +@print{} Watchpoint 1: $1 +gawk> @kbd{w $2} @ii{Imposta il punto d'osservazione su} $2 +@print{} Watchpoint 2: $2 +gawk> @kbd{r} @ii{Avvia il programma} +@print{} Partenza del programma: +@print{} Mi fermo in Rule ... +@print{} Watchpoint 1: $1 @ii{Scatta punto d'osservazione} +@print{} Old value: "" +@print{} New value: "abc" +@print{} main() a `test.awk':1 +@print{} 1 @{ print typeof($1), typeof($2) @} +gawk> @kbd{n} @ii{Prosegui @dots{}} +@print{} Watchpoint 2: $2 @ii{Scatta punto d'osservazione} +@print{} Old value: "" +@print{} New value: "123" +@print{} main() a `test.awk':1 +@print{} 1 @{ print typeof($1), typeof($2) @} +gawk> @kbd{n} @ii{Prende il risultato da} typeof() +@print{} strnum number @ii{Il risultato per} $2 @ii{non @`e corretto} +@c "normally" o "abnormally" @`e in inglese senza possibilit@`a di modifiche. +@print{} Programma completato normally, valore in uscita: 0 +gawk> @kbd{quit} +@end example + +In questo caso, la richiesta di confrontare il nuovo valore di @code{$2} +con quello vecchio ha richiesto che @command{gawk} lo valutasse e +stabilisse che era proprio un numero, e questo @`e riflesso nel risultato di +@code{typeof()}. + +Casi come questi in cui il debugger non @`e trasparente rispetto all'esecuzione +del programma dovrebbero essere rari. Nel caso che se ne trovi uno, si +prega di segnalarlo (@pxref{Bug}). +@end ignore + +@ignore +Look forward to a future release when these and other missing features may +be added, and of course feel free to try to add them yourself! +@end ignore + +@node Sommario sul debug +@section Sommario + +@itemize @value{BULLET} +@item +Raramente i programmi funzionano bene al primo colpo. Trovare gli errori +che contengono +viene chiamato @dfn{debugging}, e un programma che aiuta a trovarli @`e un +@dfn{debugger}. @command{gawk} ha un debugger incorporato che funziona in +modo molto simile al debugger GNU, GDB. + +@item +I debugger possono eseguire il programma un'istruzione per volta, esaminare e +cambiare i +valori delle variabili e dei vettori, e fanno tante altre cose per +permettere di comprendere cosa sta facendo effettivamente il programma in un +dato momento (a differenza del comportamento atteso). + +@item +Come la maggior parte dei debugger, il debugger di @command{gawk} funziona in +termini di stack frame, e si possono inserire sia punti d'interruzione +(interruzioni a un certo punto del codice) sia punti d'osservazione +(interruzioni quando il valore di un dato cambia). + +@item +La serie di comandi del debugger @`e abbastanza completa, e permette di +monitorare i +punti d'interruzione, l'esecuzione, la visualizzazione e la +modifica dei dati, di lavorare con le pile, ottenere informazioni, e di +svolgere altri compiti. + +@item +Se la libreria GNU Readline @`e disponibile al momento della compilazione di +@command{gawk}, viene usata dal debugger per fornire la cronologia della riga +di comando e delle modifiche apportate durante il debug. + +@item +Normalmente, il debugger non influenza il programma che sta controllando, +ma questo pu@`o succedere occasionalmente. + +@end itemize + +@node Calcolo con precisione arbitraria +@chapter Calcolo con precisione arbitraria con @command{gawk} +@cindex precisione arbitraria +@cindex precisione multipla +@cindex precisione infinita +@cindex virgola mobile, numeri in@comma{} precisione arbitraria + +In questo @value{CHAPTER} si introducono alcuni concetti base su come i +computer +eseguono i calcoli e si definiscono alcuni termini importanti. +Si continua poi descrivendo il calcolo in virgola mobile, +che @`e quello che @command{awk} usa per tutte le sue operazioni aritmetiche, +e si prosegue con +una trattazione del calcolo in virgola mobile con precisione arbitraria, +una funzionalit@`a disponibile solo in @command{gawk}. Si passa poi a +illustrare i numeri interi a precisione arbitraria e si conclude con una +descrizione di alcuni punti sui quali @command{gawk} e lo standard POSIX non +sono esattamente in accordo. + +@quotation NOTA +La maggior parte degli utenti di @command{gawk} pu@`o saltare senza patemi +d'animo +questo capitolo. Tuttavia, se si vogliono eseguire calcoli scientifici con +@command{gawk}, questo @`e il luogo adatto per imparare a farlo. +@end quotation + +@menu +* Aritmetica del computer:: Una rapida introduzione alla matematica del + computer. +* Definizioni matematiche:: Definizione dei termini usati. +* Funzionalit@`a MPFR:: Funzionalit@`a MPFR in @command{gawk}. +* Cautela col calcolo in VM:: Cose da sapere. +* Interi a precisione arbitraria:: Calcolo con numeri interi a precisione + arbitraria con @command{gawk}. +* Problemi virgola mobile POSIX:: Confronto tra standard e uso corrente. +* Sommario virgola mobile:: Sommario della trattazione della + virgola mobile. +@end menu + +@node Aritmetica del computer +@section Una descrizione generale dell'aritmetica del computer + +Sinora, abbiamo avuto a che fare con dati come numeri o stringhe. Ultimamente, +comunque, i computer rappresentano ogni cosa in termini di @dfn{cifre binarie}, +o @dfn{bit}. Una cifra decimale pu@`o assumere uno di 10 valori: da zero a +nove. Una cifra binaria pu@`o assumere uno di due valori: zero o uno. Usando +il sistema binario, i computer (e i programmi per computer) possono +rappresentare e manipolare dati numerici e dati costituiti da caratteri. In +generale, tanti pi@`u bit @`e possibile usare per rappresentare una determinata +cosa, tanto maggiore sar@`a l'intervallo dei possibili valori che essa potr@`a +assumere. + +I moderni calcolatori possono eseguire calcoli numerici in almeno due modi, e +spesso anche di pi@`u. Ogni tipo di calcolo usa una diversa rappresentazione +(organizzazione dei bit) dei numeri. Le modalit@`a di calcolo che ci interessano +sono: + +@table @asis +@item Calcolo decimale +Questo @`e il tipo di calcolo che s'impara alle scuole elementari, usando +carta e penna (o anche una calcolatrice). In teoria, i numeri possono avere un +numero arbitrario di cifre su ambo i lati del separatore decimale, e il +risultato di un'operazione @`e sempre esatto. + +Alcuni sistemi moderni possono eseguire calcoli decimali direttamente, +tramite apposite istruzioni disponibili +nell'hardware dell'elaboratore, ma normalmente si ha necessit@`a di una speciale +libreria software che consenta di effettuare le operazioni desiderate. +Ci sono anche librerie che svolgono i calcoli decimali interamente +per via software. + +Anche se alcuni utenti si aspettano che @command{gawk} effettui delle +operazioni usando numeri in base decimale,@footnote{Non sappiamo perch@'e se +lo aspettino, ma @`e cos@`{@dotless{i}}.} non @`e questo quello che succede. + +@item La matematica coi numeri interi +A scuola ci hanno insegnato che i valori interi erano quei numeri privi di una +parte frazionaria, come 1, 42, o @minus{}17. +Il vantaggio dei numeri interi @`e che essi rappresentano dei valori in maniera +esatta. Lo svantaggio @`e che i numeri rappresentabili sono limitati. + +@cindex senza segno, interi +@cindex segno, interi senza +@cindex interi senza segno +Nei calcolatori, i valori interi sono di due tipi: @dfn{con segno} e +@dfn{senza segno}. I valori con segno possono essere negativi o positivi, +mentre i valori senza segno sono sempre maggiori o uguali a zero. + +Nei sistemi informatici, il calcolo con valori interi @`e esatto, ma il possibile +campo di variazione dei valori @`e limitato. L'elaborazione con numeri interi @`e +pi@`u veloce di quella con numeri a virgola mobile. + +@item La matematica coi numeri a virgola mobile +I numeri a virgola mobile rappresentano quelli che a scuola sono chiamati +numeri ``reali'' (cio@`e, quelli che hanno una parte frazionaria, come +3.1415927). Il vantaggio dei numeri a virgola mobile @`e che essi possono +rappresentare uno spettro di valori molto pi@`u ampio di quello rappresentato dai +numeri interi. Lo svantaggio @`e che ci sono numeri che essi non possono +rappresentare in modo esatto. + +I computer moderni possono eseguire calcoli su valori a virgola mobile +nell'hardware dell'elaboratore, entro un intervallo di valori limitato. +Ci sono inoltre librerie di programmi che consentono calcoli, usando numeri a +virgola mobile, di precisione arbitraria. + +POSIX @command{awk} usa numeri a virgola mobile a @dfn{doppia precisione}, +che possono gestire pi@`u cifre rispetto ai numeri a virgola mobile a +@dfn{singola precisione}. @command{gawk} ha inoltre funzionalit@`a, descritte +in dettaglio pi@`u sotto, che lo mettono in grado di eseguire +calcoli con i numeri a virgola mobile con precisione arbitraria. +@end table + +I calcolatori operano con valori interi e a virgola mobile su diversi +intervalli. I valori interi normalmente hanno una dimensione di 32 bit o 64 bit. +I valori a virgola mobile a singola precisione occupano 32 bit, mentre i +valori a virgola mobile a doppia precisione occupano 64 bit. I valori a +virgola mobile sono sempre con segno. Il possibile campo di variazione dei +valori @`e mostrato in @ref{table-numeric-ranges}. + +@float Tabella,table-numeric-ranges +@caption{Intervalli dei valori per diverse rappresentazioni numeriche} +@multitable @columnfractions .34 .33 .33 +@headitem Rappresentazione numerica @tab Valore minimo @tab Valore massimo +@item Interi con segno a 32-bit @tab @minus{}2.147.483.648 @tab 2.147.483.647 +@item Interi senza segno a 32-bit @tab 0 @tab 4.294.967.295 +@item Interi con segno a 64-bit @tab @minus{}9.223.372.036.854.775.808 @tab 9.223.372.036.854.775.807 +@item Interi senza segno a 64-bit @tab 0 @tab 18.446.744.073.709.551.615 +@iftex +@item Virgola mobile, singola precisione (circa) @tab @math{1,175494^{-38}} @tab @math{3,402823^{38}} +@item Virgola mobile, doppia precisione (circa) @tab @math{2,225074^{-308}} @tab @math{1,797693^{308}} +@end iftex +@ifinfo +@item Virgola mobile, singola precisione (circa) @tab 1,175494e-38 @tab 3,402823e38 +@item Virgola mobile, doppia precisione (circa) @tab 2,225074e-308 @tab 1,797693e308 +@end ifinfo +@ifnottex +@ifnotinfo +@item Virgola mobile, singola precisione (circa) @tab 1,175494@sup{-38} @tab 3,402823@sup{38} +@item Virgola mobile, singola precisione (circa) @tab 2,225074@sup{-308} @tab 1,797693@sup{308} +@end ifnotinfo +@end ifnottex +@end multitable +@end float + +@node Definizioni matematiche +@section Altre cose da sapere + +Il resto di questo @value{CHAPTER} usa un certo numero di termini. Di seguito +vengono date alcune definizioni informali che dovrebbero essere utili +per la lettura di questo documento: + +@table @dfn +@item Accuratezza +L'accuratezza del calcolo sui numeri a virgola mobile indica di quanto si +avvicina il calcolo al valore reale (calcolato con carta e penna). + +@item Errore +La differenza tra quello che il risultato di un calcolo ``dovrebbe dare'' +e quello che effettivamente d@`a. @`E meglio minimizzare l'errore quanto pi@`u +possibile. + +@item Esponente +L'ordine di grandezza di un valore; +alcuni bit in un valore a virgola mobile contengono l'esponente. + +@item Inf +Un valore speciale che rappresenta l'infinito. Le operazioni tra un qualsiasi +numero e l'infinito danno infinito. + +@item Mantissa +Un valore a virgola mobile @`e formato dalla mantissa moltiplicata per 10 +alla potenza dell'esponente. Per esempio, in @code{1,2345e67}, +la mantissa @`e @code{1,2345}. + +@item Modalit@`a di arrotondamento +Come i numeri vanno arrotondati, per eccesso o per difetto, quando necessario. +Maggiori dettagli verranno forniti in seguito. + +@item NaN +``Not a number'' (Non un Numero).@footnote{Grazie a Michael +Brennan per questa descrizione, che abbiamo parafrasato, e per gli esempi.} Un +valore speciale che risulta da un calcolo che non ha risposta come numero +reale. In tal caso, i programmi possono o ricevere un'eccezione di virgola +mobile, o restituire @code{NaN} come risultato. Lo standard IEEE 754 +consiglia che i sistemi restituiscano @code{NaN}. Alcuni esempi: + +@table @code +@item sqrt(-1) +La radice quadrata di @minus{}1 ha senso nell'insieme dei numeri complessi, +ma non nell'insieme dei numeri reali, +per cui il risultato @`e @code{NaN}. + +@item log(-8) +Il logaritmo di @minus{}8 @`e fuori dal dominio di @code{log()}, +per cui il risultato @`e @code{NaN}. +@end table + +@item Normalizzato (formato) +Come la mantissa (vedi oltre in questa lista) @`e usualmente memorizzata. Il +valore viene aggiustato in modo che il primo bit sia sempre uno, +e in questo modo l'uno iniziale @`e supposto presente (per come viene +generato il numero), ma non @`e memorizzato fisicamente. +Questo fornisce un bit di precisione in pi@`u. + +@item Precisione +Il numero di bit usati per rappresentare un numero a virgola mobile. +Pi@`u sono i bit, e maggiore @`e l'intervallo di cifre che si possono +rappresentare. +Le precisioni binaria e decimale sono legate in modo approssimativo, secondo +la formula: + +@display +@iftex +@math{prec = 3.322 @cdot dps} +@end iftex +@ifnottex +@ifnotdocbook +@var{prec} = 3.322 * @var{dps} +@end ifnotdocbook +@end ifnottex +@docbook +<emphasis>prec</emphasis> = 3.322 ⋅ <emphasis>dps</emphasis> +@end docbook +@end display + +@noindent +Qui, @emph{prec} indica la precisione binaria +(misurata in bit) e @emph{dps} (abbreviazione di "decimal places") +indica le cifre decimali. + +@item Stabilit@`a +Dal@uref{http://en.wikipedia.org/wiki/Numerical_stability, +l'articolo di Wikipedia sulla stabilit@`a numerica}: +``I calcoli per i quali si pu@`o dimostrare che non amplificano gli errori di +approssimazione sono chiamati @dfn{numericamente stabili}.'' +@end table + +Si veda @uref{http://en.wikipedia.org/wiki/Accuracy_and_precision, +l'articolo di Wikipedia su accuratezza e precisione} per maggiori informazioni +su questi due termini. + +Sui computer moderni, l'unit@`a di calcolo in virgola mobile usa la +rappresentazione e le operazioni definite dallo standard IEEE 754. +Tre dei tipi definiti nello standard IEEE 754 sono: +32-bit singola precisione, +64-bit doppia precisione e +128-bit quadrupla precisione. +Lo standard specifica anche formati a precisione estesa +per consentire una maggiore precisione e campi di variazione degli esponenti +pi@`u ampi. (@command{awk} usa solo il formato a 64-bit doppia precisione.) + +@ref{table-ieee-formats} elenca la precisione e i valori di campo +dell'esponente per i principali formati binari IEEE 754. + +@float Tabella,table-ieee-formats +@caption{Valori per i principali formati IEEE} +@multitable @columnfractions .20 .20 .20 .20 .20 +@headitem Nome @tab Bit totali @tab Precisione @tab Esponente minimo @tab Esponente massimo +@item Singola @tab 32 @tab 24 @tab @minus{}126 @tab +127 +@item Doppia @tab 64 @tab 53 @tab @minus{}1022 @tab +1023 +@item Quadrupla @tab 128 @tab 113 @tab @minus{}16382 @tab +16383 +@end multitable +@end float + +@quotation NOTA +I numeri che descrivono la precisione includono la cifra 1 iniziale +implicita, il che equivale ad avere un bit in pi@`u nella mantissa. +@end quotation + +@node Funzionalit@`a MPFR +@section Funzionalit@`a per il calcolo a precisione arbitraria in @command{gawk} + +Per default, @command{gawk} usa i valori in virgola mobile a doppia precisione +disponibili nell'hardware del sistema su cui viene eseguito. +Tuttavia, se @`e stato compilato in modo da includere questa funzionalit@`a +ed @`e stata specificata +l'opzione da riga di comando @option{-M}, @command{gawk} usa le librerie +@uref{http://www.mpfr.org, GNU MPFR} e @uref{http://gmplib.org, GNU MP} (GMP) +per effettuare calcoli sui numeri con una precisione arbitraria. +Si pu@`o verificare se il supporto a MPFR @`e disponibile in questo modo: + +@example +$ @kbd{gawk --version} +@print{} GNU Awk 4.1.2, API: 1.1 (GNU MPFR 3.1.0-p3, GNU MP 5.0.2) +@print{} Copyright (C) 1989, 1991-2015 Free Software Foundation. +@dots{} +@end example + +@noindent +(I numeri di versione visualizzati possono essere diversi. Non importa; +l'importante @`e che siano presenti GNU MPFR e GNU MP +nel testo restituito.) + +Inoltre, ci sono alcuni elementi disponibili nel vettore @code{PROCINFO} +per fornire informazioni sulle librerie MPFR e GMP +(@pxref{Variabili auto-assegnate}). + +La libreria MPFR d@`a un controllo accurato sulle precisioni e sulle modalit@`a di +arrotondamento, e d@`a risultati correttamente arrotondati, riproducibili e +indipendenti dalla piattaforma. Con l'opzione da riga di comando @option{-M}, +tutti gli operatori aritmetici e le funzioni in virgola mobile possono +produrre risultati a ogni livello di precisione supportato da MPFR. + +Due variabili predefinite, @code{PREC} e @code{ROUNDMODE}, +danno il controllo sulla precisione di elaborazione e sulla modalit@`a di +arrotondamento. La precisione e la modalit@`a di arrotondamento sono impostate +a livello globale per ogni operazione da eseguire. +@xref{Impostare la precisione} e +@iftex +la +@end iftex +@ref{Impostare modi di arrotondare} +per maggiori informazioni. + +@node Cautela col calcolo in VM +@section Calcolo in virgola mobile: @dfn{Caveat Emptor}! + +@quotation +@i{L'ora di matematica @`e ostica!} +@author Teen Talk Barbie, luglio 1992 +@end quotation + +Questa @value{SECTION} fornisce un quadro dettagliato dei problemi che +si presentano quando si eseguono molti calcoli in virgola +mobile.@footnote{C'@`e un saggio molto bello +@uref{http://www.validlab.com/goldberg/paper.pdf, sul calcolo in +virgola mobile} di David Goldberg, ``What Every Computer Scientist Should Know +About Floating-Point Arithmetic,'' +@cite{ACM Computing Surveys} @strong{23}, 1 (1991-03): 5-48. Vale la pena di +leggerlo, se si @`e interessati a scendere nei dettagli, per@`o richiede delle +conoscenze informatiche.} +Le spiegazioni fornite valgono sia per il calcolo in virgola mobile +effettuato direttamente dall'hardware del computer, sia per quello +ottenuto tramite il software per la precisione arbitraria. + +@quotation ATTENZIONE +Le informazioni fornite in questa sede sono deliberatamente di tipo generale. +Se si devono eseguire calcoli complessi col computer, si dovrebbero prima +ottenere ulteriori informazioni, e non basarsi solo su quanto qui detto. +@end quotation + +@menu +* Inesattezza nei calcoli:: La matematica in virgola mobile non @`e + esatta. +* Ottenere la precisione:: Ottenere pi@`u precisione richiede qualche + sforzo. +* Tentare di arrotondare:: Aggiungere cifre di precisione e arrotondare. +* Impostare la precisione:: Come impostare la precisione. +* Impostare modi di arrotondare:: Impostare le modalit@`a di arrotondamento. +@end menu + +@node Inesattezza nei calcoli +@subsection La matematica in virgola mobile non @`e esatta + +Le rappresentazioni e i calcoli con numeri a virgola mobile binari sono +inesatti. Semplici valori come 0,1 non possono essere rappresentati in modo +preciso usando numeri a virgola mobile binari, e la limitata precisione dei +numeri a virgola mobile significa che piccoli cambiamenti nell'ordine delle +operazioni o la precisione di memorizzazione di operazioni +intermedie pu@`o cambiare il +risultato. Per rendere la situazione pi@`u difficile, nel calcolo in virgola +mobile con precisione arbitraria, si pu@`o impostare la precisione prima di +eseguire un calcolo, per@`o non si pu@`o sapere con certezza quale sar@`a +il numero di cifre decimali esatte nel risultato finale. + +@menu +* Rappresentazioni inesatte:: I numeri non sono rappresentati esattamente. +* Confronti tra valori in VM:: Come confrontare valori in virgola mobile. +* Gli errori si sommano:: Gli errori diventano sempre maggiori. +@end menu + +@node Rappresentazioni inesatte +@subsubsection Molti numeri non possono essere rappresentati esattamente + +Perci@`o, prima di iniziare a scrivere del codice, si dovrebbe pensare +al risultato che si vuole effettivamente ottenere e a cosa realmente accade. +Si considerino i due numeri nel seguente esempio: + +@example +x = 0.875 # 1/2 + 1/4 + 1/8 +y = 0.425 +@end example + +Diversamente dal numero in @code{y}, il numero memorizzato in @code{x} +@`e rappresentabile esattamente nel formato binario, perch@'e pu@`o essere +scritto come somma finita di una o pi@`u frazioni i cui denominatori sono tutti +multipli di due. +Quando @command{gawk} legge un numero a virgola mobile dal sorgente di un +programma, arrotonda automaticamente quel numero alla precisione, quale che +sia, supportata dal computer in uso. Se si tenta di stampare il contenuto +numerico di una variabile usando una stringa di formato in uscita di +@code{"%.17g"}, il valore restituito pu@`o non essere lo stesso numero assegnato +a quella variabile: + +@example +$ @kbd{gawk 'BEGIN @{ x = 0.875; y = 0.425} +> @kbd{ printf("%0.17g, %0.17g\n", x, y) @}'} +@print{} 0.875, 0.42499999999999999 +@end example + +Spesso l'errore @`e talmente piccolo da non essere neppure notato, e se @`e stato +notato, si pu@`o sempre specificare il grado di precisione si vuole nell'output. +In genere questo @`e una stringa di formato come @code{"%.15g"} che, se usata +nell'esempio precedente, d@`a luogo a un output identico all'input. + +@node Confronti tra valori in VM +@subsubsection Fare attenzione quando si confrontano valori + +Poich@'e la rappresentazione interna del computer +pu@`o discostarsi, sia pur di poco, dal valore +esatto, confrontare dei valori a virgola mobile per vedere se sono esattamente +uguali @`e generalmente una pessima idea. Questo @`e un esempio in cui tale +confronto non funziona come dovrebbe: + +@example +$ @kbd{gawk 'BEGIN @{ print (0.1 + 12.2 == 12.3) @}'} +@print{} 0 +@end example + +Il metodo generalmente seguito per confrontare valori a virgola mobile +consiste nel controllare se la differenza tra loro @`e minore di un certo valore +(chiamato @dfn{delta}, o @dfn{tolleranza}). Quel che si deve decidere @`e qual +@`e il valore minimo di delta +adeguato. Il codice per far ci@`o @`e qualcosa del genere: + +@example +delta = 0.00001 # per esempio +differenza = abs(a) - abs(b) # sottrazione dei due valori +if (differenza < delta) + # va bene +else + # non va bene +@end example + +@noindent +(Si presuppone che sia stata definita in qualche parte del programma una +semplice funzione che restituisce il valore assoluto di un numero, +chiamata @code{abs()}.) + +@node Gli errori si sommano +@subsubsection Gli errori diventano sempre maggiori + +La perdita di accuratezza in un singolo calcolo con numeri a virgola mobile +generalmente non dovrebbe destare preoccupazione. Tuttavia, se si calcola un +valore che @`e una sequenza di operazioni in virgola mobile, l'errore si pu@`o +accumulare e influire sensibilmente sul risultato del calcolo stesso. +Qui sotto vediamo un tentativo di calcolare il valore di @value{PI} usando +una delle sue rappresentazioni +come somma di una serie di numeri: + +@example +BEGIN @{ + x = 1.0 / sqrt(3.0) + n = 6 + for (i = 1; i < 30; i++) @{ + n = n * 2.0 + x = (sqrt(x * x + 1) - 1) / x + printf("%.15f\n", n * x) + @} +@} +@end example + +Quando viene eseguito, gli errori iniziali si propagano nei calcoli +successivi, facendo terminare il ciclo prematuramente dopo un tentativo di +divisione per zero: + +@example +$ @kbd{gawk -f pi.awk} +@print{} 3.215390309173475 +@print{} 3.159659942097510 +@print{} 3.146086215131467 +@print{} 3.142714599645573 +@dots{} +@print{} 3.224515243534819 +@print{} 2.791117213058638 +@print{} 0.000000000000000 +@error{} gawk: pi.awk:6: fatale: tentativo di dividere per zero +@end example + +Ecco un altro esempio in cui l'inaccuratezza nelle rappresentazioni interne +porta a un risultato inatteso: + +@example +$ @kbd{gawk 'BEGIN @{} +> @kbd{for (d = 1.1; d <= 1.5; d += 0.1) # esegue il ciclo cinque volte (?)} +> @kbd{i++} +> @kbd{print i} +> @kbd{@}'} +@print{} 4 +@end example + +@node Ottenere la precisione +@subsection Ottenere la precisione voluta + +Pu@`o il calcolo con precisione arbitraria dare risultati esatti? Non ci sono +risposte facili. Le regole standard dell'algebra spesso non valgono +nei calcoli con precisione arbitraria. +Tra le altre cose, le leggi distributiva e associativa non sono rispettate +completamente, e l'ordine dell'operazione pu@`o essere importante per +il calcolo. +Errori di arrotondamento, perdite di precisione che si accumulano, e +valori molto vicini allo zero sono spesso causa di problemi. + +Quando @command{gawk} verifica l'eguaglianza delle espressioni +@samp{0.1 + 12.2} e @samp{12.3} usando l'aritmetica a doppia precisione della +macchina, decide che non sono uguali! (@xref{Confronti tra valori in VM}.) +Si pu@`o ottenere il risultato cercato aumentando la precisione; 56 bit in +questo caso sono sufficienti: + +@example +$ @kbd{gawk -M -v PREC=56 'BEGIN @{ print (0.1 + 12.2 == 12.3) @}'} +@print{} 1 +@end example + +Se aggiungere pi@`u bit @`e una buona cosa, aggiungerne ancora di pi@`u +@`e meglio? +Ecco cosa succede se si usa un valore di @code{PREC} ancora pi@`u alto: + +@example +$ @kbd{gawk -M -v PREC=201 'BEGIN @{ print (0.1 + 12.2 == 12.3) @}'} +@print{} 0 +@end example + +Non @`e un bug di @command{gawk} o della libreria MPFR. +@`E facile dimenticare che il numero finito di bit usato per memorizzare il +valore spesso @`e solo un'approssimazione dopo un opportuno arrotondamento. Il +test di uguaglianza riesce se e solo se @emph{tutti} i bit dei due operandi +sono esattamente gli stessi. Poich@'e questo non @`e necessariamente vero dopo un +calcolo in virgola mobile con una determinata precisione e con una modalit@`a di +arrotondamento valida, un test di eguaglianza convenzionale potrebbe non +riuscire. Invece, il test riesce confrontando i due numeri per vedere se la +differenza tra di loro rientra in un delta accettabile. + +In applicazioni dove sono sufficienti fino a 15 cifre decimali, +il calcolo in doppia precisione eseguito dall'hardware del computer +pu@`o essere una buona soluzione, +e in genere @`e pi@`u veloce. Per@`o bisogna tener presente che ogni operazione in +virgola mobile pu@`o subire un nuovo errore di arrotondamento con conseguenze +catastrofiche, come si @`e visto nel precedente tentativo di calcolare il valore +di @value{PI}. +In tali casi una precisione supplementare pu@`o aumentare la stabilit@`a e +l'accuratezza del calcolo. + +Oltre a ci@`o, bisogna tenere conto del fatto che +addizioni ripetute non sono necessariamente equivalenti a una moltiplicazione +nell'aritmetica in virgola mobile. Nell'esempio visto in +@ref{Gli errori si sommano}: + +@example +$ @kbd{gawk 'BEGIN @{} +> @kbd{for (d = 1.1; d <= 1.5; d += 0.1) # ciclo eseguito cinque volte (?)} +> @kbd{i++} +> @kbd{print i} +> @kbd{@}'} +@print{} 4 +@end example + +@noindent +non @`e detto che, scegliendo per @code{PREC} un valore arbitrariamente alto, si +riesca a ottenere il risultato corretto. La riformulazione del problema in +questione @`e spesso il modo corretto di comportari in tali situazioni. + +@node Tentare di arrotondare +@subsection Tentare di aggiungere bit di precisione e arrotondare + +Invece dell'aritmetica in virgola mobile con precisione arbitraria, +spesso tutto ci@`o di cui si ha bisogno @`e un aggiustamento della logica +o di un diverso ordine delle operazioni nei calcoli. +La stabilit@`a e l'accuratezza del calcolo di @value{PI} +nel primo esempio possono essere migliorata usando la seguente semplice +trasformazione algebrica: + +@example +(sqrt(x * x + 1) - 1) / x @equiv{} x / (sqrt(x * x + 1) + 1) +@end example + +@noindent +Dopo aver fatto questo cambiamento, il programma converge verso +@value{PI} in meno di 30 iterazioni: + +@example +$ @kbd{gawk -f pi2.awk} +@print{} 3.215390309173473 +@print{} 3.159659942097501 +@print{} 3.146086215131436 +@print{} 3.142714599645370 +@print{} 3.141873049979825 +@dots{} +@print{} 3.141592653589797 +@print{} 3.141592653589797 +@end example + +@node Impostare la precisione +@subsection Impostare la precisione + +@command{gawk} usa una precisione di lavoro a livello globale; non tiene +traccia della precisione e accuratezza dei singoli numeri. Eseguendo +un'operazione aritmetica o chiamando una funzione predefinita, il risultato +viene arrotondato alla precisione di lavoro. La precisione di lavoro di default +@`e di 53 bit, modificabile usando la variabile predefinita @code{PREC}. Si pu@`o +anche impostare il valore a una delle stringhe predefinite (non importa se +scritte in maiuscolo o minuscolo) elencate in +@ref{table-predefined-precision-strings}, +per emulare un formato binario che segue lo standard IEEE 754. + +@float Tabella,table-predefined-precision-strings +@caption{Stringhe di precisione predefinita per @code{PREC}} +@multitable {@code{"double"}} {12345678901234567890123456789012345} +@headitem @code{PREC} @tab formato binario IEEE 754 +@item @code{"half"} @tab 16-bit mezza precisione +@item @code{"single"} @tab 32-bit singole precisione di base +@item @code{"double"} @tab 64-bit doppia precisione di base +@item @code{"quad"} @tab 128-bit quadrupla precisione di base +@item @code{"oct"} @tab 256-bit ottupla precisione +@end multitable +@end float + +Il seguente esempio illustra gli effetti del cambiamento di precisione +sulle operazioni aritmetiche: + +@example +$ @kbd{gawk -M -v PREC=100 'BEGIN @{ x = 1.0e-400; print x + 0} +> @kbd{PREC = "double"; print x + 0 @}'} +@print{} 1e-400 +@print{} 0 +@end example + +@quotation ATTENZIONE +Diffidare delle costanti in virgola mobile! Quando si legge una costante in +virgola mobile dal codice sorgente di un programma, @command{gawk} usa la +precisione di default (quella del formato @code{double} di C), a meno che non +venga richiesto, tramite la variabile speciale @code{PREC} fornita +sulla riga di comando, di memorizzarla internamente come un numero MPFR. +Cambiare la precisione tramite @code{PREC} nel testo del programma @emph{non} +cambia la precisione di una costante. + +Se si deve rappresentare una costante in virgola mobile con una precisione +maggiore di quella di default e non @`e possibile usare un assegnamento a +@code{PREC} da riga di comando, si dovrebbe definire la costante o come +stringa, o come numero razionale, ove possibile. L'esempio seguente illustra le +differenze tra i diversi modi di stampare una costante in virgola mobile: + +@example +$ @kbd{gawk -M 'BEGIN @{ PREC = 113; printf("%0.25f\n", 0.1) @}'} +@print{} 0.1000000000000000055511151 +$ @kbd{gawk -M -v PREC=113 'BEGIN @{ printf("%0.25f\n", 0.1) @}'} +@print{} 0.1000000000000000000000000 +$ @kbd{gawk -M 'BEGIN @{ PREC = 113; printf("%0.25f\n", "0.1") @}'} +@print{} 0.1000000000000000000000000 +$ @kbd{gawk -M 'BEGIN @{ PREC = 113; printf("%0.25f\n", 1/10) @}'} +@print{} 0.1000000000000000000000000 +@end example +@end quotation + +@node Impostare modi di arrotondare +@subsection Impostare la modalit@`a di arrotondamento + +La variabile @code{ROUNDMODE} permette di controllare a livello di programma +la modalit@`a di arrotondamento. +La corrispondenza tra @code{ROUNDMODE} e le modalit@`a di arrotondamento IEEE +@`e mostrata in @ref{table-gawk-rounding-modes}. + +@float Tabella,table-gawk-rounding-modes +@caption{Modalit@`a di arrotondamento in @command{gawk} } +@multitable @columnfractions .45 .30 .25 +@headitem Modalit@`a di arrotondamento @tab Nome IEEE @tab @code{ROUNDMODE} +@item Arrotonda al pi@`u vicino, o a un numero pari @tab @code{roundTiesToEven} @tab @code{"N"} o @code{"n"} +@item Arrotonda verso infinito @tab @code{roundTowardPositive} @tab @code{"U"} o @code{"u"} +@item Arrotonda verso meno infinito @tab @code{roundTowardNegative} @tab @code{"D"} o @code{"d"} +@item Arrotonda verso zero (troncamento) @tab @code{roundTowardZero} @tab @code{"Z"} o @code{"z"} +@item Arrotonda al pi@`u vicino, o per eccesso @tab @code{roundTiesToAway} @tab @code{"A"} o @code{"a"} +@end multitable +@end float + +@code{ROUNDMODE} ha @code{"N"} come valore di default, ovvero si usa la +modalit@`a di arrotondamento IEEE 754 @code{roundTiesToEven}. +In @ref{table-gawk-rounding-modes}, il valore @code{"A"} seleziona +@code{roundTiesToAway}. Questo @`e applicabile solo se la versione in uso +della libreria MPFR lo supporta; altrimenti, l'impostazione di @code{ROUNDMODE} +ad @code{"A"} non ha alcun effetto. + +La modalit@`a di default @code{roundTiesToEven} @`e la pi@`u preferita, ma allo +stesso tempo +la meno intuitiva. Questo metodo fa la cosa ovvia per la maggior parte dei +valori, arrotondandoli per eccesso o per difetto alla cifra pi@`u prossima. +Per esempio, arrotondando 1.132 alle due cifre decimali si ottiene 1.13, +e 1.157 viene arrotondato a 1.16. + +Tuttavia, se si deve arrotondare un valore posto esattamente a met@`a strada, +le cose non funzionano come probabilmente si insegna a scuola. +In questo caso, il numero @`e arrotondato alla cifra @emph{pari} pi@`u prossima. +Cos@`{@dotless{i}} arrotondando 0.125 alle due cifre si arrotonda per difetto a 0.12, +ma arrotondando 0.6875 alle tre cifre si arrotonda per eccesso a 0.688. +Probabilmente ci si @`e gi@`a imbattuti in questa modalit@`a di arrotondamento +usando @code{printf} per formattare numeri a virgola mobile. +Per esempio: + +@example +BEGIN @{ + x = -4.5 + for (i = 1; i < 10; i++) @{ + x += 1.0 + printf("%4.1f => %2.0f\n", x, x) + @} +@} +@end example + +@noindent +produce il seguente output quando viene eseguito sul sistema +dell'autore:@footnote{@`E possibile che l'output sia completamente diverso, se la +libreria C presente nel sistema in uso non si conforma, per @code{printf}, +alla regola IEEE 754 +di arrotondamento al valore pari in caso di equidistanza.} + +@example +-3.5 => -4 +-2.5 => -2 +-1.5 => -2 +-0.5 => 0 + 0.5 => 0 + 1.5 => 2 + 2.5 => 2 + 3.5 => 4 + 4.5 => 4 +@end example + +La teoria che sta dietro alla regola +@code{roundTiesToEven} @`e che gli arrotondamenti di +valori equidistanti in eccesso e in difetto si distribuiscono pi@`u o meno +uniformemente, con la possibile conseguenza che errori di arrotondamento +ripetuti tendono ad annullarsi a vicenda. Questa @`e la modalit@`a di +arrotondamento di default per funzioni e operatori di calcolo secondo IEEE 754. + +Le altre modalit@`a di arrotondamento sono usate raramente. Gli arrotondamenti +verso l'infinito (@code{roundTowardPositive}) e verso il meno infinito +(@code{roundTowardNegative}) vengono spesso usati per eseguire calcoli su +intervalli, dove si adotta questa modalit@`a di arrotondamento per calcolare +i limiti superiore e inferiore per l'intervallo di valori in uscita. +La modalit@`a +@code{roundTowardZero} pu@`o essere usata per convertire numeri a virgola mobile +in numeri interi. La modalit@`a di arrotondamento @code{roundTiesToAway} +arrotonda il risultato al numero pi@`u vicino, e in caso di equidistanza +arrotonda per eccesso. + +Qualche esperto di analisi numerica dir@`a che la scelta dello stile di +arrotondamento ha un grandissimo impatto sul risultato finale, e consiglier@`a +di attendere sino al risultato finale dopo ogni arrotondamento. Invece, +spesso si possono evitare problemi legati a errori di arrotondamento +impostando all'inizio la precisione a un valore sufficientemente maggiore +della precisione desiderata, in modo che il cumulo degli errori di +arrotondamento non influisca sul +risultato finale. Se si ha il dubbio che i risultati del calcolo contengano +un'accumulazione di errori di arrotondamento, occorre, per accertare la cosa, +controllare se si verifica una differenza significativa nell'output +cambiando la modalit@`a di arrotondamento. + +@node Interi a precisione arbitraria +@section Aritmetica dei numeri interi a precisione arbitraria con @command{gawk} +@cindex numeri interi a precisione arbitraria +@cindex interi a precisione arbitraria +@cindex precisione arbitraria, interi a + +Quando viene specificata l'opzione @option{-M}, +@command{gawk} esegue tutti i calcoli sui numeri interi usando gli interi a +precisione arbitraria della libreria GMP. Qualsiasi numero che appaia come un +intero in un sorgente o in un @value{DF} @`e memorizzato come intero a precisione +arbitraria. La dimensione del numero intero ha come limite solo la memoria +disponibile. Per esempio, il seguente programma calcola +@iftex +@math{5^{4^{3^{2}}}}, +@end iftex +@ifinfo +5^4^3^2, +@end ifinfo +@ifnottex +@ifnotinfo +5@sup{4@sup{3@sup{2}}}, +@end ifnotinfo +@end ifnottex +il cui risultato @`e oltre i limiti degli ordinari valori a virgola mobile a +doppia precisione dei processori: + +@example +$ @kbd{gawk -M 'BEGIN @{} +> @kbd{x = 5^4^3^2} +> @kbd{print "numero di cifre =", length(x)} +> @kbd{print substr(x, 1, 20), "...", substr(x, length(x) - 19, 20)} +> @kbd{@}'} +@print{} numero di cifre = 183231 +@print{} 62060698786608744707 ... 92256259918212890625 +@end example + +Se invece si dovesse calcolare lo stesso valore usando valori a virgola mobile +con precisione arbitraria, la precisione necessaria per il risultato corretto +(usando +la formula +@iftex +@math{prec = 3.322 @cdot dps}) +sarebbe @math{3.322 @cdot 183231}, +@end iftex +@ifnottex +@ifnotdocbook +@samp{prec = 3.322 * dps}) +sarebbe 3.322 x 183231, +@end ifnotdocbook +@end ifnottex +@docbook +<emphasis>prec</emphasis> = 3.322 ⋅ <emphasis>dps</emphasis>) +would be +<emphasis>prec</emphasis> = 3.322 ⋅ 183231, +@end docbook +o 608693. + +Il risultato di un'operazione aritmetica tra un intero e un valore a virgola +mobile @`e un valore a virgola mobile con precisione uguale alla precisione di +lavoro. Il seguente programma calcola l'ottavo termine nella successione di +Sylvester@footnote{Weisstein, Eric W. +@cite{Sylvester's Sequence}. From MathWorld---A Wolfram Web Resource +@w{(@url{http://mathworld.wolfram.com/SylvestersSequence.html}).}} +usando una ricorrenza: + +@example +$ @kbd{gawk -M 'BEGIN @{} +> @kbd{s = 2.0} +> @kbd{for (i = 1; i <= 7; i++)} +> @kbd{s = s * (s - 1) + 1} +> @kbd{print s} +> @kbd{@}'} +@print{} 113423713055421845118910464 +@end example + +Il risultato mostrato differisce dal numero effettivo, +113.423.713.055.421.844.361.000.443, +perch@'e la precisione di default di 53 bit non @`e suffciente per rappresentare +esattamente il risultato in virgola mobile. Si pu@`o o aumentare la precisione +(in questo caso bastano 100 bit), o sostituire la costante in virgola mobile +@samp{2.0} con un intero, per eseguire tutti i calcoli usando l'aritmetica con +gli interi per ottenere l'output corretto. + +A volte @command{gawk} deve convertire implicitamente un intero con precisione +arbitraria in un valore a virgola mobile con precisione arbitraria. +Ci@`o si rende necessario +principalmente perch@'e la libreria MPFR non sempre prevede l'interfaccia +necessaria per elaborare interi a precisione arbitraria o numeri di tipo +eterogeneo come richiesto da un'operazione o funzione. In tal caso, la +precisione viene impostata al minimo valore necessario per una conversione +esatta, e non viene usata la precisione di lavoro. Se +questo non @`e quello di cui si ha bisogno o che si vuole, si pu@`o ricorrere a un +sotterfugio e convertire preventivamente l'intero in un valore a virgola +mobile, come qui di seguito: + +@example +gawk -M 'BEGIN @{ n = 13; print (n + 0.0) % 2.0 @}' +@end example + +Si pu@`o evitare completamente questo passaggio specificando il numero come +valore a virgola mobile fin dall'inizio: + +@example +gawk -M 'BEGIN @{ n = 13.0; print n % 2.0 @}' +@end example + +Si noti che, per questo specifico esempio, probabilmente @`e meglio +semplicemente specificare: + +@example +gawk -M 'BEGIN @{ n = 13; print n % 2 @}' +@end example + +Dividendo due interi a precisione arbitraria con @samp{/} o con @samp{%}, il +risultato @`e tipicamente un valore a virgola mobile con precisione arbitraria +(a meno che il risultato non sia un numero intero esatto). +Per eseguire divisioni intere o calcolare moduli con interi a precisione +arbitraria, usare la funzione predefinita +@code{intdiv()} (@pxref{Funzioni numeriche}). + +Si pu@`o simulare la funzione @code{intdiv()} in @command{awk} standard +usando questa funzione definita dall'utente: + +@example +@c file eg/lib/intdiv.awk +# intdiv --- fa una divisione intera + +@c endfile +@ignore +@c file eg/lib/intdiv.awk +# +# Arnold Robbins, arnold@@skeeve.com, Public Domain +# July, 2014 +# +# Name changed from div() to intdiv() +# April, 2015 + +@c endfile + +@end ignore +@c file eg/lib/intdiv.awk +function intdiv(numerator, denominator, result) +@{ + split("", result) + + numerator = int(numerator) + denominator = int(denominator) + result["quotient"] = int(numerator / denominator) + result["remainder"] = int(numerator % denominator) + + return 0.0 +@} +@c endfile +@end example + +Il seguente programma d'esempio, proposto da Katie Wasserman, +usa @code{intdiv()} per +calcolare le cifre di @value{PI} al numero di cifre significative +che si @`e scelto di impostare: + +@example +@c file eg/prog/pi.awk +# pi.awk --- calcola le cifre di pi +@c endfile +@c endfile +@ignore +@c file eg/prog/pi.awk +# +# Katie Wasserman, katie@@wass.net +# August 2014 +@c endfile +@end ignore +@c file eg/prog/pi.awk + +BEGIN @{ + cifre = 100000 + due = 2 * 10 ^ cifre + pi = due + for (m = cifre * 4; m > 0; --m) @{ + d = m * 2 + 1 + x = pi * m + intdiv(x, d, risultato) + pi = risultato["quotient"] + pi = pi + due + @} + print pi +@} +@c endfile +@end example + +@ignore +Date: Wed, 20 Aug 2014 10:19:11 -0400 +To: arnold@skeeve.com +From: Katherine Wasserman <katie@wass.net> +Subject: Re: computation of digits of pi? + +Arnold, + +>The program that you sent to compute the digits of pi using div(). Is +>that some standard algorithm that every math student knows? If so, +>what's it called? + +It's not that well known but it's not that obscure either + +It's Euler's modification to Newton's method for calculating pi. + +Take a look at lines (23) - (25) here: http://mathworld.wolfram.com/PiFormulas.htm + +The algorithm I wrote simply expands the multiply by 2 and works from the innermost expression outwards. I used this to program HP calculators because it's quite easy to modify for tiny memory devices with smallish word sizes. + +http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/articles.cgi?read=899 + +-Katie +@end ignore + +Quando gli fu chiesto dell'algoritmo usato, Katie rispose: + +@quotation +Non @`e quello pi@`u noto ma nemmeno quello pi@`u incomprensibile. +@`E la variante di Eulero al metodo di Newton per il calcolo del Pi greco. +Si vedano le righe (23) - (25) nel sito: +@uref{http://mathworld.wolfram.com/PiFormulas.html}. + +L'algoritmo che ho scritto semplicemente espande il moltiplicare per 2 e +lavora dall'espressione pi@`u interna verso l'esterno. Ho usato questo per +programmare delle calcolatrici HP perch@'e @`e piuttosto facile da adattare ai +dispositivi di scarsa memoria con dimensioni di parola piuttosto piccole. +Si veda +@uref{http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/articles.cgi?read=899}. +@end quotation + +@node Problemi virgola mobile POSIX +@section Confronto tra standard e uso corrente + +Per diverso tempo, @command{awk} ha convertito le stringhe dall'aspetto non +numerico nel valore numerico zero, quando richiesto. Per di pi@`u, la +definizione originaria del linguaggio e lo standard POSIX originale prevedevano +che @command{awk} riconoscesse solo i numeri decimali (base 10), e non i numeri +ottali (base 8) o esadecimali (base 16). + +Le modifiche nel linguaggio degli standard POSIX 2001 e 2004 possono essere +interpretate nel senso che @command{awk} debba fornire delle funzionalit@`a +aggiuntive. Queste sono: + +@itemize @value{BULLET} +@item +Interpretazione del valore dei dati a virgola mobile specificati in notazione +esadecimale (p.es., @code{0xDEADBEEF}). (Da notare: valore dei dati letti, +@emph{non} costanti facenti parte del codice sorgente.) + +@item +Supporto per i valori a virgola mobile speciali IEEE 754 ``not a number'' +(NaN), pi@`u infinito (``inf'') e meno infinito (``@minus{}inf''). +In particolare, il formato per questi valori @`e quello specificato dallo +standard C ISO 1999, che non distingue maiuscole/minuscole e pu@`o consentire +caratteri aggiuntivi dipendenti dall'implementazione dopo il @samp{nan}, e +consentire o @samp{inf} o @samp{infinity}. +@end itemize + +Il primo problema @`e che entrambe le modifiche sono deviazioni evidenti +dalla prassi consolidata: + +@itemize @value{BULLET} +@item +Il manutentore di @command{gawk} crede che supportare i valori a virgola mobile +esadecimali, nello specifico, sia sbagliato, e che non sia mai stata intenzione +dell'autore originale di introdurlo nel linguaggio. + +@item +Consentire che stringhe completamente alfabetiche abbiano valori numerici +validi @`e anch'essa una deviazione molto marcata dalla prassi consolidata. +@end itemize + +Il secondo problema @`e che il manutentore di @command{gawk} crede che questa +interpretazione dello standard, che richiede una certa dimestichezza col +linguaggio giuridico per essere compresa, non sempre @`e stata +colta dai normali sviluppatori. In altre parole, ``Sappiamo come siete +arrivati sin qui, ma non pensiamo che questo sia il posto dove volete essere.'' + +Recependo queste argomentazioni, e cercando nel contempo di assicurare la +compatibilit@`a con le versioni precedenti dello standard, lo standard POSIX 2008 +ha aggiunto delle formulazioni esplicite per consentire l'uso da parte di +@command{awk}, solo a richiesta, dei valori a virgola mobile esadecimali e +dei valori speciali +``@dfn{not a number}'' e infinito. + +Sebbene il manutentore di @command{gawk} continui a credere che introdurre +queste funzionalit@`a sia sconsigliabile, ci@`o nonostante, sui sistemi che +supportano i valori in virgola mobile IEEE, sembra giusto fornire +@emph{qualche} +possibilit@`a di usare i valori NaN e infinito. La soluzione implementata +in @command{gawk} @`e questa: + +@itemize @value{BULLET} +@item +Se @`e stata specificata l'opzione da riga di comando @option{--posix}, +@command{gawk} non +interviene. I valori di stringa sono passati direttamente alla funzione +@code{strtod()} della libreria di sistema, e se quest'ultima restituisce +senza errori un valore numerico, +esso viene usato.@footnote{L'avete voluto, tenetevelo.} +Per definizione, i risultati non sono portabili su diversi sistemi; +e sono anche piuttosto sorprendenti: + +@example +$ @kbd{echo nanny | gawk --posix '@{ print $1 + 0 @}'} +@print{} nan +$ @kbd{echo 0xDeadBeef | gawk --posix '@{ print $1 + 0 @}'} +@print{} 3735928559 +@end example + +@item +Senza l'opzione @option{--posix}, @command{gawk} interpreta i quattro valori di stringa +@samp{+inf}, +@samp{-inf}, +@samp{+nan} +e +@samp{-nan} +in modo speciale, producendo i corrispondenti valori numerici speciali. +Il segno iniziale serve per segnalare a @command{gawk} (e all'utente) +che il valore @`e realmente numerico. I numeri a virgola mobile esadecimali +non sono consentiti (a meno di non usare anche @option{--non-decimal-data}, +che @emph{non} @`e consigliabile). Per esempio: + +@example +$ @kbd{echo nanny | gawk '@{ print $1 + 0 @}'} +@print{} 0 +$ @kbd{echo +nan | gawk '@{ print $1 + 0 @}'} +@print{} nan +$ @kbd{echo 0xDeadBeef | gawk '@{ print $1 + 0 @}'} +@print{} 0 +@end example + +@command{gawk} ignora la distinzione maiuscole/minuscole nei quattro valori +speciali. Cos@`{@dotless{i}}, @samp{+nan} e @samp{+NaN} sono la stessa cosa. +@end itemize + +@node Sommario virgola mobile +@section Sommario + +@itemize @value{BULLET} +@item +La maggior parte dell'aritmetica al calcolatore @`e fatta usando numeri interi +oppure +valori a virgola mobile. L'@command{awk} standard usa valori a virgola mobile +a doppia precisione. + +@item +Nei primi anni '90 Barbie disse erroneamente, ``L'ora di matematica @`e +ostica!'' Sebbene la matematica non sia ostica, l'aritmetica a virgola +mobile non @`e proprio come la +matematica ``carta e penna'', e bisogna prestare attenzione: + +@c nested list +@itemize @value{MINUS} +@item +Non tutti i numeri possono essere rappresentati in modo esatto. + +@item +Per confrontare dei valori bisognerebbe usare un delta, invece di farlo +direttamente con @samp{==} e @samp{!=}. + +@item +Gli errori si accumulano. + +@item +Le operazioni non sempre sono esattamente associative o distributive. +@end itemize + +@item +Aumentare l'accuratezza pu@`o essere d'aiuto, ma non @`e una panacea. + +@item +Spesso, aumentare la precisione e poi arrotondare al numero di cifre +desiderato produce risultati soddisfacenti. + +@item +Specificare l'opzione @option{-M} (o @option{--bignum}) per abilitare +il calcolo MPFR. +Usare @code{PREC} per impostare la precisione in bit, e +@code{ROUNDMODE} per impostare la modalit@`a di arrotondamento tra quelle +previste nello standard IEEE 754. + +@item +Specificando l'opzione @option{-M}, @command{gawk} esegue calcoli su interi a precisione +arbitraria usando la libreria GMP. In tal modo si ha una maggiore velocit@`a e +una pi@`u efficiente allocazione dello spazio rispetto all'uso di MPFR per +eseguire gli stessi calcoli. + +@item +Ci sono diverse aree per quanto attiene ai numeri a virgola mobile in cui +@command{gawk} @`e in disaccordo con lo standard POSIX. +@`E importante averlo ben presente. + +@item +In generale, non vi @`e alcun bisogno di essere eccessivamente diffidenti verso i +risultati del calcolo in virgola mobile. La lezione da ricordare @`e che +il calcolo in virgola mobile @`e sempre pi@`u complesso di quello che si fa con +carta e penna. Per trarre vantaggio dalla potenza del calcolo in virgola +mobile, bisogna conoscere i suoi limiti e stare all'interno di essi. +Per la maggior parte degli usi occasionali del calcolo in virgola mobile, si +possono ottenere i risultati attesi semplicemente arrotondando la +visualizzazione dei risultati finali al giusto numero di cifre decimali +significative. + +@item +Come consiglio generale, evitare di rappresentare dati numerici in maniera +tale da far sembrare che la precisione sia maggiore di quella effettivamente +necessaria. + +@end itemize + +@node Estensioni dinamiche +@chapter Scrivere estensioni per @command{gawk} +@cindex estensioni caricate dinamicamente +@cindex dinamiche, estensioni + +@`E possibile aggiungere nuove funzioni, scritte in C o C++, a @command{gawk} +usando librerie caricate dinamicamente. Questa funzionalit@`a @`e disponibile +su sistemi che supportano le funzioni C @code{dlopen()} e @code{dlsym()}. +Questo @value{CHAPTER} descrive come creare estensioni usando codice scritto +in C o C++. + +Chi @`e completamente digiuno di programmazione in C pu@`o tranquillamente +saltare questo @value{CHAPTER}, ma potrebbe valer la pena di dare un'occhiata +alla documentazione sulle estensioni che sono installate insieme a +@command{gawk} (@pxref{Esempi di estensione}), +e alle informazioni sul progetto @code{gawkextlib} (@pxref{gawkextlib}). +Gli esempi di estensione sono automaticamente compilati e installati quando +si installa @command{gawk}. + +@quotation NOTA +Se si specifica l'opzione @option{--sandbox}, le estensioni non sono +disponibili +(@pxref{Opzioni}). +@end quotation + +@menu +* Introduzione alle estensioni:: Cos'@`e un'estensione. +* Licenza delle estensioni:: Una nota riguardo al tipo di licenza. +* Panoramica sul meccanismo delle estensioni:: Una panoramica sul meccanismo + delle estensioni. +* Descrizione dell'API delle estensioni:: Una descrizione completa dell'API. +* Trovare le estensioni:: Come @command{gawk} trova le estensioni + compilate. +* Esempio di estensione:: Esempio di codice C di un'estensione. +* Esempi di estensione:: Le estensioni di esempio incluse con + @command{gawk}. +* gawkextlib:: Il progetto @code{gawkextlib}. +* Sommario delle estensioni:: Sommario delle estensioni. +* Esercizi sulle estensioni:: Esercizi. +@end menu + +@node Introduzione alle estensioni +@section Cos'@`e un'estensione + +@cindex plug-in +Un'@dfn{estensione} (talora chiamata @dfn{plug-in}) @`e un frammento di codice +compilato esternamente che @command{gawk} pu@`o caricare in fase di esecuzione +per ottenere funzionalit@`a ulteriori, che vanno ad aggiungersi a quelle di +@command{gawk} descritte nel resto di questo @value{DOCUMENT}. + +Le estensioni sono utili perch@'e consentono (ovviamente) di estendere le +funzionalit@`a di @command{gawk}. Per esempio, possono permettere l'uso di +@dfn{chiamate di sistema} (come @code{chdir()} per cambiare directory) +e di altre routine di libreria C potenzialmente utili. Come per la maggior +parte del software, ``il cielo @`e il limite''; se si riesce a immaginare +qualcosa che si vuol fare e che @`e possibile programmare in C o C++, +si pu@`o scrivere un'estensione che lo faccia! + +Le estensioni sono scritte in C o C++, usando l'API (@dfn{Application +Programming Interface}) definita per questo scopo dagli sviluppatori di +@command{gawk}. Il resto di questo @value{CHAPTER} descrive +le possibilit@`a offerte dall'API e come usarle, +e illustra una piccola estensione di esempio. Inoltre, sono documentati +gli esempi di estensione inclusi nella distribuzione di @command{gawk} +e viene descritto il progetto @code{gawkextlib}. +@ifclear FOR_PRINT +@xref{Progetto delle estensioni}, per una disamina degli obiettivi e del +progetto del meccanismo delle estensioni. +@end ifclear +@ifset FOR_PRINT +Si veda @uref{http://www.gnu.org/software/gawk/manual/html_node/estensione-Design.html} +per una disamina degli obiettivi e del +progetto del meccanismo delle estensioni. +@end ifset + +@node Licenza delle estensioni +@section Tipo di licenza delle estensioni + +Ogni estensione dinamica dev'essere distribuita in base a una licenza che sia +compatibile con la licenza GNU GPL (@pxref{Copia}). + +Per far sapere a @command{gawk} che la licenza @`e quella corretta, +l'estensione deve definire il simbolo globale +@code{plugin_is_GPL_compatibile}. Se tale simbolo non @`e stato definito, +@command{gawk} termina con un messaggio di errore fatale al momento del +caricamente dell'estensione. + +Il tipo dichiarato per il suddetto simbolo dev'essere @code{int}. Esso non +deve tuttavia essere presente in ogni sezione allocata. +Il controllo in essere si limita a constatare che quel simbolo esiste a +livello globale. +Qualcosa del genere pu@`o essere sufficiente: + +@example +int plugin_is_GPL_compatible; +@end example + +@node Panoramica sul meccanismo delle estensioni +@section Una panoramica sul funzionamento ad alto livello + +La comunicazione tra +@command{gawk} e un'estensione @`e bidirezionale. Dapprima, quando +un'estensione @`e caricata, @command{gawk} le passa un puntatore a una struttura +(@code{struct}) i cui campi sono dei puntatori di funzione. +@ifnotdocbook +Questo si pu@`o vedere in @ref{figura-carica-estensione}. +@end ifnotdocbook +@ifdocbook +Questo si pu@`o vedere in @inlineraw{docbook, <xref linkend="figura-carica-estensione"/>}. +@end ifdocbook + +@ifnotdocbook +@float Figura,figura-carica-estensione +@caption{Caricamento dell'estensione} +@ifclear SMALLPRINT +@center @image{api-figura1, , , Caricamento dell'estensione} +@end ifclear +@ifset SMALLPRINT +@center @image{api-figura1, 11cm, , Caricamento dell'estensione} +@end ifset + +@end float +@end ifnotdocbook + +@docbook +<figure id="figura-carica-estensione" float="0"> +<title>Caricamento dell'estensione</title> +<mediaobject> +<imageobject role="web"><imagedata fileref="api-figura1.png" format="PNG"/></imageobject> +</mediaobject> +</figure> +@end docbook + +L'estensione @`e in grado di chiamare funzioni all'interno di @command{gawk} +utilizzando questi puntatori a funzione, in fase di esecuzione, senza aver +bisogno di accedere (in fase di compilazione), ai simboli di @command{gawk}. +Uno di questi puntatori a funzione punta a una funzione che serve per +``registrare'' nuove funzioni. +@ifnotdocbook +Questo @`e mostrato in @ref{figura-registrare-una-nuova-funzione}. +@end ifnotdocbook +@ifdocbook +Questo @`e shown in @inlineraw{docbook, <xref linkend="figura-registrare-una-nuova-funzione"/>}. +@end ifdocbook + +@ifnotdocbook +@float Figura,figura-registrare-una-nuova-funzione +@caption{Registrare una nuova funzione} +@ifclear SMALLPRINT +@center @image{api-figura2, , , Registrare una nuova funzione} +@end ifclear +@ifset SMALLPRINT +@center @image{api-figura2, 11cm , , Registrare una nuova funzione} +@end ifset +@end float +@end ifnotdocbook + +@docbook +<figure id="figura-registrare-una-nuova-funzione" float="0"> +<title>Registering a new function</title> +<mediaobject> +<imageobject role="web"><imagedata fileref="api-figura2.png" format="PNG"/></imageobject> +</mediaobject> +</figure> +@end docbook + +Nella direzione opposta, l'estensione registra le sue nuove funzioni +con @command{gawk} passando dei puntatori che puntano alle funzioni che +implementano la nuova funzionalit@`a, (p.es. @code{do_chdir()}). @command{gawk} +associa il puntatore a funzione con un nome ed @`e in grado di chiamarlo in +seguito, usando una convenzione di chiamata predefinita. +@ifnotdocbook +Questo @`e mostrato in @ref{figura-chiamata-nuova-funzione}. +@end ifnotdocbook +@ifdocbook +Questo @`e mostrato in @inlineraw{docbook, <xref linkend="figura-chiamata-nuova-funzione"/>}. +@end ifdocbook + +@ifnotdocbook +@float Figura,figura-chiamata-nuova-funzione +@caption{Chiamata della nuova funzione} +@ifclear SMALLPRINT +@center @image{api-figura3, , , Chiamata della nuova funzione} +@end ifclear +@ifset SMALLPRINT +@center @image{api-figura3,11cm , , Chiamata della nuova funzione} +@end ifset +@end float +@end ifnotdocbook + +@docbook +<figure id="figura-chiamata-nuova-funzione" float="0"> +<title>Chiamata della nuova funzione</title> +<mediaobject> +<imageobject role="web"><imagedata fileref="api-figura3.png" format="PNG"/></imageobject> +</mediaobject> +</figure> +@end docbook + +La funzione @code{do_@var{xxx}()}, a sua volta, utilizza i puntatori a +funzione nella struttura (@code{struct}) API per svolgere il proprio compito, +come aggiornare variabili o vettori, stampare messaggi, impostare la +variabile @code{ERRNO}, e cos@`{@dotless{i}} via. + +Delle macro di servizio rendono la chiamata effettuata utilizzando +i puntatori simile a quella delle funzioni normali, in modo che il codice +sorgente delle estensioni rimanga sufficientemente leggibile e comprensibile. + +Sebbene tutto ci@`o possa sembrare piuttosto complesso, il risultato @`e che il +codice sorgente dell'estensione @`e abbastanza intuitivo da scrivere e da +leggere. Lo si pu@`o constatare nell'estensione di esempio +@file{filefuncs.c} +(@pxref{Esempio di estensione}), come pure nel codice @file{testext.c}, +che testa l'interfaccia di programmazione (API). + +Ecco alcuni ulteriori dettagli: + +@itemize @value{BULLET} +@item +L'API fornisce accesso ai valori delle variabili @command{gawk} +@code{do_@var{xxx}}, che memorizzano opzioni della riga di comando come +@code{do_lint}, @code{do_profiling}, e cos@`{@dotless{i}} via (@pxref{Variabili dell'estensione API}). +Questi valori sono solo informativi: un'estensione non pu@`o modificarli +all'interno di @command{gawk}. Oltre a ci@`o, il tentativo di assegnare loro +dei valori produce un errore quando l'estensione viene compilata. + +@item +L'API fornisce anche i numeri che identificano la specifica versione di +@command{gawk}, in modo che un'estensione possa controllare se il +comando @command{gawk} che l'ha caricata @`e in grado di supportare le +funzionalit@`a utilizzate nell'estensione. (Discrepanze tra le versioni +``non dovrebbero'' accadere, ma si sa come vanno @emph{queste} cose.) +@xref{Versione dell'estensione} per ulteriori dettagli. +@end itemize + +@node Descrizione dell'API delle estensioni +@section Una descrizione completa dell'API +@cindex estensioni, API delle +@cindex API, delle estensioni + +Il codice sorgente scritto in C o C++ per un'estensione deve includere il +file di intestazione +@file{gawkapi.h}, che dichiara le funzioni e definisce i tipi di dati +usati per comunicare con @command{gawk}. +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +(non breve) @value{SECTION} descrive l'API in detttaglio. + +@menu +* Intro funzioni API delle estensioni:: Introduzione alle funzioni dell'API. +* Tipi di dati generali:: I tipi di dati. +* Funzioni di allocazione memoria:: Funzioni per allocare memoria. +* Funzioni di costruzione:: Funzioni per creare valori. +* Funzioni di registrazione:: Funzioni per registrare cose con + @command{gawk}. +* Stampare messaggi:: Funzioni per stampare messaggi. +* Aggiornare @code{ERRNO}:: Funzioni per aggiornare @code{ERRNO}. +* Richiedere valori:: Come ottenere un valore. +* Accedere ai parametri:: Funzioni per accedere ai parametri. +* Accedere alla tabella simboli:: Funzioni per accedere alle variabili + globali +* Manipolazione di vettori:: Funzioni per lavorare coi vettori. +* Ridirezione API:: Come accedere alla ridirezioni e + modificarle. +* Variabili dell'estensione API:: Variabili fornite dall'API. +* Codice predefinito di un'estensione API:: Codice predefinito di + interfaccia API. +* Modifiche dalla versione API 1:: Modifiche dalla versione 1 dell'API. +@end menu + +@node Intro funzioni API delle estensioni +@subsection Introduzione alle funzioni dell'API + +L'accesso a funzionalit@`a interne a @command{gawk} @`e effettuato +con una chiamata che usa i puntatori a funzione resi disponibili +all'estensione. + +Puntatori a funzioni API sono previsti per i seguenti tipi di operazioni: + +@itemize @value{BULLET} +@item +Allocare, riallocare e liberare memoria. + +@item +Registrare funzioni. Si possono registrare: + +@c nested list +@itemize @value{MINUS} +@item +Funzioni di estensione +@item +Funzioni ausiliarie di pulizia (@dfn{callbacks}) +@item +Una stringa di caratteri che identifica la versione +@item +Funzioni per analizzare l'input +@item +Funzioni per modificare l'output +@item +Processori bidirezionali +@end itemize + +Tutti questi elementi sono spiegati dettagliatamente nel resto di questo @value{CHAPTER}. + +@item +Stampare messaggi fatali, di avvertimento e quelli generati dall'opzione +``lint''. + +@item +Modificare @code{ERRNO} o annullarne il valore. + +@item +Accedere a parametri, compresa la possibilit@`a di definire come vettore +un parametro ancora indefinito. + +@item +Accedere alla "tabella dei simboli": procurarsi il valore di una variabile +globale, crearne una nuova o modificarne una gi@`a esistente. + +@item +Creare ed eliminare valori nascosti; ci@`o rende possibile usare un +particolare valore per pi@`u di una variabile, e pu@`o migliorare parecchio +le prestazioni. + +@item +Manipolare vettori: + +@itemize @value{MINUS} +@item +Ritrovare il valore di elementi del vettore, aggiungerne di nuovi, +cancellare e modificare elementi esistenti. + +@item +Ottenere il numero di elementi presenti in un vettore + +@item +Creare un nuovo vettore + +@item +Cancellare un intero vettore + +@item +Appiattire un vettore per poter facilmente eseguire un ciclo, in stile C, +su tutti i suoi indici ed elementi +@end itemize + +@item +Accedere a ridirezioni e manipolarle. + +@end itemize + +Alcune osservazioni riguardo all'uso dell'API: + +@itemize @value{BULLET} +@item +I seguenti tipi di variabili, macro e/o funzioni sono resi disponibili +nel file @file{gawkapi.h}. Perch@'e siano utilizzabili, i rispettivi file di +intestazione standard indicati devono essere stati specificati @emph{prima} +di includere @file{gawkapi.h}: + +@c FIXME: Make this as a float at some point. +@multitable {@code{memset()}, @code{memcpy()}} {@code{<sys/types.h>}} +@headitem Elemento C @tab File d'intestazione +@item @code{EOF} @tab @code{<stdio.h>} +@item valori di @code{errno} @tab @code{<errno.h>} +@item @code{FILE} @tab @code{<stdio.h>} +@item @code{NULL} @tab @code{<stddef.h>} +@item @code{memcpy()} @tab @code{<string.h>} +@item @code{memset()} @tab @code{<string.h>} +@item @code{size_t} @tab @code{<sys/types.h>} +@item @code{struct stat} @tab @code{<sys/stat.h>} +@end multitable + +Per ragioni di portabilit@`a, specialmente per sistemi +che non sono interamente aderenti agli standard, occorre assicurarsi di +includere i file corretti nel modo corretto. Questa richiesta mira +a mantenere il file @file{gawkapi.h} ordinato, invece che farlo diventare +un'accozzaglia di problemi di portabilit@`a, quale si pu@`o vedere in alcune +parti del codice sorgente di @command{gawk}. + +@item +Il file @file{gawkapi.h} pu@`o essere incluso pi@`u volte, senza conseguenze +negative. Tuttavia sarebbe meglio evitare di farlo, per uno +stile di programmazione migliore. + +@item +Sebbene l'API usi solo funzionalit@`a ISO C 90, c'@`e un'eccezione; le funzione +``costruttrici'' usano la parola chiave @code{inline}. Se il compilatore in +uso non supporta questa parola chiave, si dovrebbe specificare sulla +riga di comando il parametro @samp{-Dinline=''} oppure usare gli strumenti +Autotools GNU e includere un file +@file{config.h} nel codice sorgente delle estensioni. + +@item +Tutti i puntatori messi a disposizione da @command{gawk} puntano ad aree +di memoria gestite da @command{gawk} e dovrebbero essere trattati +dall'estensione come in sola lettura. Le aree di memoria che contengono @emph{tutte} le stringhe passate a +@command{gawk} dall'estensione @emph{devono} provenire da una chiamata a +@code{gawk_malloc()}, @code{gawk_calloc()} o @code{gawk_realloc()}, +e sono gestite da @command{gawk} da quel punto in avanti. + +@item +L'API definisce parecchie semplici @code{struct} che mappano dei valori +come sono visti da @command{awk}. Un valore pu@`o essere un numero @code{double} +(a virgola mobile, in doppia precisione), una stringa o un +vettore (come @`e il caso per i vettori multidimensionali o nella creazione di +un nuovo vettore). + +I valori di tipo stringa sono costituiti da un puntatore e da una lunghezza, +poich@'e nella stringa possono essere presenti dei caratteri @sc{nul} +(zeri binari, che normalmente marcano la fine di una stringa). + +@quotation NOTA +Di proposito, @command{gawk} immagazzina le stringhe usando la codifica +multibyte correntemente in uso (come definita dalle variabili d'ambiente +@env{LC_@var{xxx}}) e non usando dei caratteri larghi (ovvero due byte per +ogni carattere). Ci@`o riflette il modo con cui @command{gawk} memorizza le +stringhe internamente, e anche il modo in cui i caratteri sono +verosimilmente letti dai file in input e scritti nei file in output. +@end quotation + +@quotation NOTA +I valori di una stringa passati a un'estensione da @command{gawk} hanno +sempre un carattere @sc{nul} alla fine (come delimitatore). Quindi @`e +possibile usare senza inconvenienti tali valori di stringa per chiamare +funzioni di libreria standard e routine di sistema. Tuttavia, poich@'e +@command{gawk} consente che all'interno di una stringa di dati possano +essere presenti caratteri @sc{nul}, si dovrebbe controllare che la +lunghezza di ogni stringa passata un'estensione coincida con il valore +restituito dalla funzione @code{strlen()} per la stringa stessa. +@end quotation + +@item +Per ottenere un valore (p.es. quello di un parametro o quello di una +variabile globale, oppure di un elemento di un vettore), l'estensione chiede +un tipo specifico di variabile (numero, stringa, +scalare, @dfn{value cookie} [si veda pi@`u avanti], vettore o ``undefined''). +Quando la richiesta @`e +``undefined,'' il valore restituito sar@`a quello originale della variabile in +questione. + +In ogni caso, se la richiesta e il tipo effettivo della variabile non +corrispondono, la funzione di accesso restituisce ``false'' e fornisce il +tipo proprio della variabile, in modo che l'estensione possa, p.es., +stampare un messaggio di errore +(del tipo ``ricevuto uno scalare, invece del vettore previsto''). + +@c This is documented in the header file and needs some expanding upon. +@c The table there should be presented here +@end itemize + +Si possono chiamare le funzioni dell'API usando i puntatori a funzione +direttamente, ma l'interfaccia non @`e molto elegante. Per permettere al +codice sorgente delle estensioni di assomigliare di pi@`u a un codice normale, +il file di intestazione @file{gawkapi.h} definisce parecchie +macro da usare nel codice sorgente dell'estensione. +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} presenta le macro come se si trattasse di funzioni. + +@node Tipi di dati generali +@subsection I tipi di dati di impiego generale + +@cindex Robbins, Arnold +@cindex Ramey, Chet +@quotation +@i{Ho un vero rapporto di amore/odio con le @dfn{unioni}.} +@author Arnold Robbins +@end quotation + +@quotation +@i{Questo @`e ci@`o che contraddistingue le @dfn{unioni}: il compilatore @`e +in grado di accomodare le cose in modo da far coesistere amore e odio.} +@author Chet Ramey +@end quotation + +L'estensione API definisce un certo numero di semplici tipi di dato e +strutture di uso generale. Ulteriori strutture di dati, pi@`u specializzate, +saranno introdotte +@ifnotinfo +nelle successive +@end ifnotinfo +@ifinfo +nei successivi +@end ifinfo +@value{SECTIONS}, insieme alle funzioni che ne fanno uso. + +I tipi di dati e le strutture di uso generale sono le seguenti: + +@table @code +@item typedef void *awk_ext_id_t; +Un valore di questo tipo @`e trasmesso da @command{gawk} a un'estensione nel +momento in cui viene caricata. Tale valore dev'essere restituito +a @command{gawk} come primo parametro di ogni funzione API. + +@item #define awk_const @dots{} +Questa macro genera delle @samp{costanti} nel momento in cui si compila +un'estensione, e non genera nulla quando si compila il comando @command{gawk} +vero e proprio. Ci@`o rende alcuni +campi nelle strutture dei dati dell'API non alterabili dal codice sorgente +dell'estensione, ma consente al comando @command{gawk} di usarle secondo +necessit@`a. + +@item typedef enum awk_bool @{ +@itemx @ @ @ @ awk_false = 0, +@itemx @ @ @ @ awk_true +@itemx @} awk_bool_t; +Un semplice tipo di variabile booleana. + +@item typedef struct awk_string @{ +@itemx @ @ @ @ char *str;@ @ @ @ @ /* dati veri e propri */ +@itemx @ @ @ @ size_t len;@ @ @ @ /* lunghezza degli stessi, in caratteri */ +@itemx @} awk_string_t; +Questo rappresenta una stringa modificabile. @command{gawk} @`e responsabile +per la gestione della memoria utilizzata, se ha fornito il valore della +stringa. Altrimenti, assume il possesso della memoria in questione. +@emph{Questa memoria dev'essere resa disponibile chiamando una delle funzioni +@code{gawk_malloc()}, @code{gawk_calloc()} o @code{gawk_realloc()}!} + +Come gi@`a detto, la rappresentazione delle stringhe in memoria usa la codifica +multibyte corrente. + +@item typedef enum @{ +@itemx @ @ @ @ AWK_UNDEFINED, +@itemx @ @ @ @ AWK_NUMBER, +@itemx @ @ @ @ AWK_STRING, +@itemx @ @ @ @ AWK_REGEX, +@itemx @ @ @ @ AWK_STRNUM, +@itemx @ @ @ @ AWK_ARRAY, +@itemx @ @ @ @ AWK_SCALAR,@ @ @ @ @ @ @ @ @ /* accesso opaco a una variabile */ +@itemx @ @ @ @ AWK_VALUE_COOKIE@ @ @ @ /* per aggiornare un valore +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ gi@`a creato */ +@itemx @} awk_valtype_t; +L'elenco @code{enum} indica di che tipo @`e un certo valore. +@`E usato nella seguente struttura @code{struct}. + +@item typedef struct awk_value @{ +@itemx @ @ @ @ awk_valtype_t val_type; +@itemx @ @ @ @ union @{ +@itemx @ @ @ @ @ @ @ @ awk_string_t@ @ @ @ @ @ @ s; +@itemx @ @ @ @ @ @ @ @ double@ @ @ @ @ @ @ @ @ @ @ @ @ d; +@itemx @ @ @ @ @ @ @ @ awk_array_t@ @ @ @ @ @ @ @ a; +@itemx @ @ @ @ @ @ @ @ awk_scalar_t@ @ @ @ @ @ @ scl; +@itemx @ @ @ @ @ @ @ @ awk_value_cookie_t@ vc; +@itemx @ @ @ @ @} u; +@itemx @} awk_value_t; +Un ``valore di @command{awk}''. +Il campo @code{val_type} indica che tipo di valore @code{union} contiene, +e ogni campo @`e del tipo appropriato. + +@item #define str_value@ @ @ @ @ @ u.s +@itemx #define strnum_value@ @ @ str_value +@itemx #define regex_value@ @ @ @ str_value +@itemx #define num_value@ @ @ @ @ @ u.d +@itemx #define array_cookie@ @ @ u.a +@itemx #define scalar_cookie@ @ u.scl +@itemx #define value_cookie@ @ @ u.vc +L'uso di queste macro rende pi@`u facile da seguire l'accesso ai campi di +@code{awk_value_t}. + +@item typedef void *awk_scalar_t; +La variabili scalari possono essere rappresentate da un tipo opaco. Questi +valori sono ottenuti da @command{gawk} e in seguito gli vengono restituiti. +Questo argomento @`e discusso in maniera generale nel testo che segue questa +lista, e pi@`u in dettaglio +@iftex +nella +@end iftex +@ifnottex +in +@end ifnottex +@ref{Tabella simboli tramite cookie}. + +@item typedef void *awk_value_cookie_t; +Un ``@dfn{value cookie}'' @`e un tipo di variabile opaca, e +rappresenta un valore nascosto. +Anche questo argomento @`e discusso in maniera generale nel testo che segue +questa lista, e pi@`u in dettaglio +@iftex +nella +@end iftex +@ifnottex +in +@end ifnottex +@ref{Valori nascosti}. + +@end table + +I valori di tipo scalare in @command{awk} sono numeri, stringhe, @dfn{strnum} +o @dfn{regexp} fortemente tipizzate. +La struttura @code{awk_value_t} rappresenta valori. +Il campo @code{val_type} indica cosa contiene @code{union}. + +Rappresentare numeri @`e facile: l'API usa una variabile C di tipo +@code{double}. Le stringhe richiedono +uno sforzo maggiore. Poich@'e +@command{gawk} consente che le stringhe contengano dei byte @sc{nul} +(a zeri binari) nel valore di una stringa, una stringa dev'essere +rappresentata da una coppia di campi che contengono il puntatore al dato vero +e proprio e la lunghezza della stringa. +@`E questo @`e il tipo @code{awk_string_t}. + +Un valore di tipo @dfn{strnum} (stringa numerica) @`e rappresentato come una +stringa e consiste di dati in input forniti dall'utente che appaiono essere +numerici. +Quando una funzione di estensione crea un valore di tipo @dfn{strnum}, il +risultato @`e una stringa che viene marcata come immessa dall'utente. La +successiva analisi da parte di @command{gawk} servir@`a poi a determinare se +la stringa appare essere un numero, e va quindi trattata come @dfn{strnum}, +invece che come una normale stringa di caratteri. + +Ci@`o @`e utile nei casi un cui una funzione di estensione desideri fare qualcosa +di paragonabile alla funzione @code{split}, la quale imposta l'attributo +di @dfn{strnum} agli elementi di vettore che crea. +Per esempio, un'estensione che implementi la divisione di record CSV +(Comma Separated Values, i cui elementi sono delimitati da virgole) +potrebbe voler usare questa funzionalit@`a. Un'altra situazione in cui ci@`o +@`e utile @`e quello di una funzione che richieda campi-dati ad una banca di +dati. La funzione @code{PQgetvalue()} della banca dati PostgreSQ, per +esempio, restituisce una stringa che pu@`o essere numerica o di tipo carattere, +a seconda del contesto. + +I valori di @dfn{regexp} fortemente tipizzate +(@pxref{Costanti @dfn{regexp} forti} non sono molto utili nelle funzioni di +estensione. Le funzioni di estensione possono stabilire di averli ricevuti, +e crearne, attribuendo valori di tipo scalare. In alternativa, @`e possibile +esaminare il testo della @dfn{regexp} utilizzando campi @code{regex_value.str} +e @code{regex_value.len}. + +Identificativi (cio@`e, nomi di variabili globali) possono essere +associati sia a valori scalari che a vettori. Inoltre, @command{gawk} +consente veri vettori di vettori, in cui ogni singolo elemento di un vettore +pu@`o a sua volta essere un vettore. La spiegazione dei vettori @`e rinviata +@iftex +alla +@end iftex +@ifnottex +a +@end ifnottex +@ref{Manipolazione di vettori}. + +La varie macro sopra elencate facilitano l'uso degli elementi delle +@code{union} come se +fossero campi in una @code{struct}; @`e questa una pratica comunemente adottata +nella scrittura di programmi in C. Questo tipo di codice @`e pi@`u semplice da +scrivere e da leggere, ma resta una responsabilit@`a @emph{del programmatore} +assicurarsi che il campo @code{val_type} rifletta correttamente il tipo +del valore contenuto nella struttura @code{awk_value_t}. + +Dal punti di vista concettuale, i primi tre campi dell'@code{union} (numero, +stringa, e vettore) sono sufficienti per lavorare con i valori @command{awk}. +Tuttavia, poich@'e l'API fornisce routine per ottenere e modificare +il valore di una variabile scalare globale usando solo il nome della +variabile, si ha qui una perdita di efficienza: @command{gawk} deve cercare +la variabile ogni volta che questa @`e utilizzata e modificata. Questo +@`e un probelma reale, non solo un problema teorico. + +Per questo motivo, se si sa che una certa estensione passer@`a molto tempo +a leggere e/o modificare il valore di una o pi@`u variabili scalari, si pu@`o +ottenere uno @dfn{scalar cookie}@footnote{Si veda +@uref{http://catb.org/jargon/html/C/cookie.html, la voce ``cookie'' +nello Jargon file} +per una definizione di @dfn{cookie}, e +@uref{http://catb.org/jargon/html/M/magic-cookie.html, la voce ``magic cookie'' +sempre nello Jargon file} per un bell'esempio. +@ifclear FOR_PRINT +Si veda anche la voce ``Cookie'' nel @ref{Glossario}. +@end ifclear +[@uref{http://jhanc.altervista.org/jargon/Intro.html, @`E disponibile in rete +anche una traduzione italiana dello Jargon file}] +} +per quella variabile, e poi usare +il @dfn{cookie} per ottenere il valore della variabile o per modificarne il +valore. +Il tipo @code{awk_scalar_t} contiene uno @dfn{scalar cookie}, e la macro +@code{scalar_cookie} fornisce accesso al valore di quel tipo +nella struttura @code{awk_value_t}. +Dato uno @dfn{scalar cookie}, @command{gawk} pu@`o trovare o modificare +direttamente il valore, come richiesto, senza bisogno di andarlo +a cercare ogni volta. + +Il tipo @code{awk_value_cookie_t} e la macro @code{value_cookie} sono simili. +Se si pensa di dover usare +lo stesso @emph{valore} numerico o la stessa @emph{stringa} per una o pi@`u +variabili, si pu@`o creare il valore una volta per tutte, mettendo da parte un +@dfn{@dfn{value cookie}} per quel valore, e in seguito specificare quel +@dfn{value cookie} quando si desidera impostare il valore di una variabile. +Ci@`o consente di risparmiare spazio in memoria all'interno del processo +di @command{gawk} e riduce il tempo richiesto per creare il valore. + +@node Funzioni di allocazione memoria +@subsection Funzioni per allocare memoria e macro di servizio +@cindex allocare memoria per estensioni +@cindex memoria, allocare per estensioni +@cindex estensioni, allocare memoria per + +L'API fornisce alcune funzioni per effettuare @dfn{allocazioni di memoria} +che possono essere passate a @command{gawk}, e anche un certo numero di +macro che possono tornare utili. +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SUBSECTION} le presenta come prototipi di funzione, nel modo +con cui il codice dell'estensione potrebbe usarle: + +@table @code +@item void *gawk_malloc(size_t size); +Chiama la versione corretta di @code{malloc()} per allocare memoria, +che pu@`o in seguito essere messa a disposizione di @command{gawk}. + +@item void *gawk_calloc(size_t nmemb, size_t size); +Chiama la versione corretta di @code{calloc()} per allocare memoria che +che pu@`o in seguito essere messa a disposizione di @command{gawk}. + +@item void *gawk_realloc(void *ptr, size_t size); +Chiama la versione corretta di @code{realloc()} per allocare memoria +che pu@`o in seguito essere messa a disposizione di @command{gawk}. + +@item void gawk_free(void *ptr); +Chiama la versione corretta di @code{free()} per liberare memoria che +era stata allocata con +@code{gawk_malloc()}, @code{gawk_calloc()} o @code{gawk_realloc()}. +@end table + +L'API deve fornire queste funzioni perch@'e @`e possibile +che un'estensione sia stata compilata e costruita usando una versione +diversa della libreria C rispetto a quella usata per il programma eseguibile +@command{gawk}.@footnote{Questo succede pi@`u spesso nei sistemi MS-Windows, +ma pu@`o capitare anche in sistemi di tipo Unix.} +Se @command{gawk} usasse la propria versione di @code{free()} per liberare +della memoria acquisita tramite una differente versione di @code{malloc()}, +il risultato sarebbe molto probabilmente differente da quello atteso. + +Due macro di utilit@`a possono essere usate per allocare memoria +tramite @code{gawk_malloc()} e +@code{gawk_realloc()}. Se l'allocazione non riesce, @command{gawk} +termina l'esecuzione con un messaggio di errore fatale. +Queste macro dovrebbero essere usate come se fossero dei richiami a +procedure che non restituiscono un codice di ritorno: + +@table @code +@item #define emalloc(pointer, type, size, message) @dots{} +Gli argomenti per questa macro sono i seguenti: + +@c nested table +@table @code +@item pointer +La variabile di tipo puntatore che punter@`a alla memoria allocata. + +@item type +Il tipo della variabile puntatore. Questo @`e usato per definire il tipo +quando si chiama @code{gawk_malloc()}. + +@item size +Il numero totale di byte da allocare. + +@item message +Un messaggio da anteporre all'eventuale messaggio di errore fatale. +Questo @`e solitamente il nome della funzione che sta usando la macro. +@end table + +@noindent +Per esempio, si potrebbe allocare il valore di una stringa cos@`{@dotless{i}}: + +@example +awk_value_t risultato; +char *message; +const char greet[] = "non v'allarmate!"; + +emalloc(message, char *, sizeof(greet), "myfunc"); +strcpy(message, greet); +make_malloced_string(message, strlen(message), & risultato); +@end example + +@item #define erealloc(pointer, type, size, message) @dots{} +Questo @`e simile a @code{emalloc()}, ma chiama @code{gawk_realloc()} +invece che @code{gawk_malloc()}. +Gli argomenti sono gli stessi della macro @code{emalloc()}. +@end table + +@node Funzioni di costruzione +@subsection Funzioni per creare valori + +L'API fornisce varie funzioni di @dfn{costruzione} per creare +valori di tipo stringa e di tipo numerico, e anche varie macro di utilit@`a. +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SUBSECTION} le presenta tutte come prototipi di funzione, nel +modo in cui il codice sorgente di +un'estensione le userebbe: + +@table @code +@item static inline awk_value_t * +@itemx make_const_string(const char *stringa, size_t lunghezza, awk_value_t *risultato); +Questa funzione mette il valore di una stringa nella variabile +@code{awk_value_t} puntata da @code{risultato}. La funzione presuppone che +@code{stringa} sia una costante stringa C +(o altri dati che formano una stringa), e automaticamente crea una +@emph{copia} dei dati che sar@`a immagazzinata in @code{risultato}. +Viene restituito il puntatore @code{risultato}. + +@item static inline awk_value_t * +@itemx make_malloced_string(const char *stringa, size_t lunghezza, awk_value_t *risultato); +Questa funzione mette il valore di una stringa nella variabile +@code{awk_value_t} puntata da @code{risultato}. Si presuppone che +@code{stringa} sia un valore @samp{char *} +che punta a dati ottenuti in precedenza per mezzo di +@code{gawk_malloc()}, @code{gawk_calloc()} o @code{gawk_realloc()}. +L'idea @`e che questi dati siano comunicati direttamente a @command{gawk}, +che se ne assume la responsabilit@`a. +Viene restituito il puntatore @code{risultato}. + +@item static inline awk_value_t * +@itemx make_null_string(awk_value_t *risultato); +Questa funzione specializzata crea una stringa nulla (il valore ``undefined'') +nella variabile @code{awk_value_t} puntata da @code{risultato}. +Viene restituito il puntatore @code{risultato}. + +@item static inline awk_value_t * +@itemx make_number(double num, awk_value_t *risultato); +Questa funzione crea semplicemente un valore numerico nella variabile +@code{awk_value_t}, puntata da @code{risultato}. + +@item static inline awk_value_t * +@itemx make_const_user_input(const char *stringa, size_t lunghezza, awk_value_t *risultato); +Questa funzione @`e identica a @code{make_const_string()}, ma la stringa @`e +marcata come input dell'utente, che dovr@`a essere trattata come @dfn{strnum} +se il contenuto della stringa appare essere numerico. + +@item static inline awk_value_t * +@itemx make_malloced_user_input(const char *stringa, size_t lunghezza, awk_value_t *risultato); +Questa funzione @`e identica a @code{make_malloced_string()}, ma la stringa @`e +marcata come input dell'utente, che dovr@`a essere trattata come @dfn{strnum} +se il contenuto della stringa appare essere numerico. + +@item static inline awk_value_t * +@itemx make_const_regex(const char *stringa, size_t lunghezza, awk_value_t *risultato); +Questa funzione crea un valore di @dfn{regexp} fortemente tipizzata, allocando una +copia della stringa. +@code{stringa} @`e l'espressione regolare, di lunghezza @code{lunghezza}. + +@item static inline awk_value_t * +@itemx make_malloced_regex(const char *stringa, size_t lunghezza, awk_value_t *risultato); +Questa funzione crea un valore di @dfn{regexp} fortemente tipizzata. +@code{stringa} @`e l'espressione regolare, di lunghezza @code{lunghezza}. +Si aspetta che @code{stringa} sia un valore di tipo @samp{char *} che punta a +dati ottenuti in precedenza tramite una chiamata a +@code{gawk_malloc()}, @code{gawk_calloc()} o @code{gawk_realloc()}. + +@end table + +@node Funzioni di registrazione +@subsection Funzioni di registrazione +@cindex registrazione di estensione +@cindex estensione, registrazione di + +Questa @value{SECTION} descrive le funzioni dell'API per +registrare parti di un'estensione con @command{gawk}. + +@menu +* Funzioni di estensione:: Registrare funzioni di estensione. +* Funzioni di exit callback:: Registrare una exit di callback. +* Stringa di versione Estensioni:: Registrare una stringa di versione. +* Analizzatori di input:: Registrare un analizzatore di input. +* Processori di output:: Registrare un processore di output. +* Processori bidirezionali:: Registrare un processore bidirezionale. +@end menu + +@node Funzioni di estensione +@subsubsection Registrare funzioni di estensione + +Le funzioni di estensione sono descritte dal seguente tracciato record: + +@example +typedef struct awk_ext_func @{ +@ @ @ @ const char *name; +@ @ @ @ awk_value_t *(*const function)(int num_actual_args, +@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_value_t *risultato, +@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ struct awk_ext_func *finfo); +@ @ @ @ const size_t max_expected_args; +@ @ @ @ const size_t min_required_args; +@ @ @ @ awk_bool_t suppress_lint; +@ @ @ @ void *data; /* puntatore di tipo opaco +@ @ @ @ a ogni informazione ulteriore */ +@} awk_ext_func_t; +@end example + +I campi sono: + +@table @code +@item const char *name; +Il nome della nuova funzione. +Il codice sorgente a livello di @command{awk} richiama la funzione usando +questo nome. +Il nome @`e una normale stringa di caratteri del linguaggio C. + +I nomi di funzione devono rispettare le stesse regole che valgono per gli +identificativi @command{awk}. +Cio@`e, devono iniziare o con una lettera dell'alfabeto inglese o con un +trattino basso, che possono essere seguiti da un numero qualsiasi di +lettere, cifre o trattini bassi. +L'uso di maiuscolo/minuscolo @`e significativo. + +@item awk_value_t *(*const function)(int num_actual_args, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_value_t *risultato, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ struct awk_ext_func *finfo); +Questo @`e un puntatore alla funzione C che fornisce la funzionalit@`a per cui +@`e stata scritta l'estensione. +La funzione deve riempire l'area di memoria puntata da @code{*risultato} con +un numero, con una stringa, oppure con una @dfn{regexp}. +@command{gawk} diventa il proprietario di tutte le stringhe di memoria. +Come gi@`a detto sopra, la stringa di memoria @emph{deve} essere stata ottenuta +usando @code{gawk_malloc()}, @code{gawk_calloc()} o @code{gawk_realloc()}. + +L'argomento @code{num_actual_args} dice alla funzione scritta in C quanti +parametri sono stati effettivamente passati dal codice chiamante all'interno +di @command{awk}. + +La funzione deve restituire il valore di @code{risultato}. +Questo @`e per utilit@`a del codice chiamante all'interno di +@command{gawk}. + +@item size_t max_expected_args; +Questo @`e il massimo numero di argomenti che la funzione si aspetta di +ricevere. +Se chiamata con un numero di argomenti maggiore di questo, e se @`e stato +richiesto il controllo @dfn{lint}, @command{gawk} stampa un messaggio di +avvertimento. Per ulteriori informazioni, si veda la descrizione di +@code{suppress_lint}, pi@`u avanti in questa lista. + +@item const size_t min_required_args; +Questo @`e il minimo numero di argomenti che la funzione si aspetta di +ricevere. +Se @`e chiamata con un numero inferiore di argomenti, @command{gawk} +stampa un messaggio di errore fatale ed esce. + +@item awk_bool_t suppress_lint; +Questo @dfn{flag} dice a @command{gawk} di non stampare un messaggio +@dfn{lint} se @`e stato richiesto un controllo @dfn{lint} e se sono stati +forniti pi@`u argomenti di quelli attesi. Una funzione di estensione pu@`o +stabilire se @command{gawk} ha gi@`a stampato almeno uno di tali messaggi +controllando se @samp{num_actual_args > finfo->max_expected_args}. +In tal caso, se la funzione non desidera la stampa di ulteriori messaggi, +dovrebbe impostare @code{finfo->suppress_lint} a @code{awk_true}. + +@item void *data; +Questo @`e un puntatore di tipo opaco a tutti quei dati che una funzione +di estensione desidera avere disponibili al momento della chiamata. +Passando alla funzione di estensione la struttura @code{awk_ext_func_t} +e avendo al suo interno questo puntatore disponibile, rende possibile +scrivere un'unica funzione C o C++ che implementa pi@`u di una funzione +di estensione a livello @command{awk}. +@end table + +Una volta preparato un record che descrive l'estensione, la funzione di +estensione va registrata con @command{gawk} usando questa funzione dell'API: + +@table @code +@item awk_bool_t add_ext_func(const char *namespace, awk_ext_func_t *func); +Questa funzione restituisce il valore @dfn{true} se ha successo, +oppure @dfn{false} in caso contrario. +Il parametro @code{namespace} non @`e usato per ora; dovrebbe puntare a una +stringa vuota (@code{""}). Il puntatore @code{func} @`e l'indirizzo di una +@code{struct} che rappresenta la funzione stessa, come descritto sopra. + +@command{gawk} non modifica ci@`o che @`e puntato da @code{func}, ma la +funzione di estensione stessa riceve questo puntatore e pu@`o modificarlo +e farlo puntare altrove, quindi il puntatore non @`e stato dichiarato +di tipo costante (@code{const}). +@end table + +La combinazione di @code{min_required_args}, @code{max_expected_args}, +e @code{suppress_lint} pu@`o ingenerare confusione. Ecco delle linee-guida +sul da farsi. + +@table @asis +@item Un numero qualsiasi di argomenti @`e valido +Impostare @code{min_required_args} and @code{max_expected_args} a zero e +impostare @code{suppress_lint} ad @code{awk_true}. + +@item Un numero minimo di argomenti @`e richiesto, ma non c'@`e un limite al numero massimo +Impostare @code{min_required_args} al minimo richiesto. +Impostare @code{max_expected_args} a zero e +impostare @code{suppress_lint} ad @code{awk_true}. + +@item Un numero minino di argomenti @`e richiesto, ma c'@`e un limite al numero massimo +Impostare @code{min_required_args} al minimo richiesto. +Impostare @code{max_expected_args} al massimo atteso. +Impostare @code{suppress_lint} ad @code{awk_false}. + +@item Un numero minino di argomenti @`e richiesto, ma c'@`e un numero massimo non superabile +Impostare @code{min_required_args} al minimo richiesto. +Impostare @code{max_expected_args} al massimo atteso. +Impostare @code{suppress_lint} ad @code{awk_false}. +Nella funzione di estensione, controllare che @code{num_actual_args} non +ecceda @code{f->max_expected_args}. Se il massimo @`e superato, stampare +un messaggio di errore fatale. +@end table + +@node Funzioni di exit callback +@subsubsection Registrare una funzione @dfn{exit callback} + +Una funzione @dfn{exit callback} @`e una funzione che @command{gawk} invoca +prima di completare l'esecuzione del programma. +Siffatte funzioni sono utili se ci sono dei compiti generali di ``pulizia'' +che dovrebbero essere effettuati nell'estensione (come chiudere connessioni a +un @dfn{database} o rilasciare altre risorse). +Si pu@`o registrare una tale +funzione con @command{gawk} per mezzo della seguente funzione: + +@table @code +@item void awk_atexit(void (*funcp)(void *data, int exit_status), +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ void *arg0); +I parametri sono: + +@c nested table +@table @code +@item funcp +Un puntatore alla funzione da chiamare prima che @command{gawk} completi +l'esecuzione. Il parametro @code{data} +sar@`a il valore originale di @code{arg0}. +Il parametro @code{exit_status} @`e il valore del codice di ritorno che +@command{gawk} intende passare alla chiamata di sistema @code{exit()} +(che termina l'esecuzione del programma). + +@item arg0 +Un puntatore a un'area dati privata che @command{gawk} mantiene perch@'e +sia poi passata alla funzione puntata da @code{funcp}. +@end table +@end table + +Le funzioni @dfn{exit callback} sono chiamate in ordine inverso rispetto +a quello con cui @`e stata fatta la registrazione con @command{gawk} +(LIFO: Last In, First Out). + +@node Stringa di versione Estensioni +@subsubsection Registrare una stringa di versione per un'estensione + +Si pu@`o registrare una stringa di versione che indica il nome e la versione +di una data estensione a @command{gawk}, come segue: + +@table @code +@item void register_ext_version(const char *version); +Registra la stringa puntata da @code{version} con @command{gawk}. +Si noti che @command{gawk} @emph{non} copia la stringa @code{version}, e +quindi questa stringa non dovrebbe essere modificata. +@end table + +@command{gawk} stampa tutte le stringhe con le versioni di estensione +registrate, quando viene invocato specificando l'opzione @option{--version}. + +@node Analizzatori di input +@subsubsection Analizzatori di input personalizzati +@cindex personalizzato, analizzatore di input +@cindex analizzatore di input personalizzato +@cindex input, analizzatore di, personalizzato + +Per default, @command{gawk} legge file di testo come input. Il valore della +variabile @code{RS} @`e usato per determinare la fine di un record, e subito +dopo la variabile @code{FS} (o @code{FIELDWIDTHS} o @code{FPAT}) viene usata +per suddividerlo in campi +@iftex +(@pxrefil{Leggere file}). +@end iftex +@ifnottex +(@pxref{Leggere file}). +@end ifnottex +Viene inoltre impostato il valore di @code{RT} +(@pxref{Variabili predefinite}). + +Se lo si desidera, @`e possibile fornire un analizzatore di input +personalizzato. Il compito di un analizzatore di input @`e di restituire un +record al codice di @command{gawk}, che poi lo elaborer@`a, accompagnato, +se necessario, da indicatori del valore e della lunghezza dei dati da usare +per @code{RT}. + +Per fornire un analizzatore personalizzato di input, occorre innanzitutto +rendere disponibili due funzioni (dove @var{XXX} @`e un nome che fa da prefisso +all'estensione intera): + +@table @code +@item awk_bool_t @var{XXX}_can_take_file(const awk_input_buf_t *iobuf); +Questa funzione esamina l'informazione disponibile in @code{iobuf} +(che vedremo tra poco). Basandosi su tale informazione, +decide se l'analizzatore di input personalizzato andr@`a usato per questo file. +Se questo @`e il caso, dovrebbe restituire @dfn{true}. Altrimenti, restituir@`a +@dfn{false}. Nessuno stato (valori di variabili, etc.) dovrebbe venire +modificato all'interno di @command{gawk}. + +@item awk_bool_t @var{XXX}_take_control_of(awk_input_buf_t *iobuf); +Quando @command{gawk} decide di passare il controllo del file a questo +analizzatore di input, richiamer@`a questa funzione. +Questa funzione a sua volta deve assegnare un valore ad alcuni campi +nella struttura @code{awk_input_buf_t} e assicurarsi che +alcune condizioni siano verificate. Dovrebbe poi restituire @dfn{true}. +Se si verifica un errore di qualche tipo, i campi in questione non dovrebbero +venire riempiti, e la funzione dovrebbe restituire @dfn{false}; in questo caso +@command{gawk} non utilizzer@`a pi@`u l'analizzatore personalizzato di input. +I dettagli sono descritti pi@`u avanti. +@end table + +L'estensione dovrebbe raccogliere queste funzioni all'interno di una +struttura @code{awk_input_parser_t}, simile a questa: + +@example +typedef struct awk_input_parser @{ + const char *name; /* nome dell'analizzatore */ + awk_bool_t (*can_take_file)(const awk_input_buf_t *iobuf); + awk_bool_t (*take_control_of)(awk_input_buf_t *iobuf); + awk_const struct awk_input_parser *awk_const next; /* per uso + di gawk */ +@} awk_input_parser_t; +@end example + +I campi sono: + +@table @code +@item const char *name; +Il nome dell'analizzatore di input. Questa @`e una normale stringa di caratteri +del linguaggio C. + +@item awk_bool_t (*can_take_file)(const awk_input_buf_t *iobuf); +Un puntatore alla funzione @code{@var{XXX}_can_take_file()}. + +@item awk_bool_t (*take_control_of)(awk_input_buf_t *iobuf); +Un puntatore alla funzione @code{@var{XXX}_take_control_of()}. + +@item awk_const struct input_parser *awk_const next; +Questa struttura @`e per uso di @command{gawk}; +per questo motivo @`e marcata @code{awk_const} in modo che l'estensione non +possa modificarla. +@end table + +I passi da seguire sono i seguenti: + +@enumerate +@item +Creare una variabile @code{static awk_input_parser_t} e inizializzarla +adeguatamente. + +@item +Quando l'estensione @`e caricata, registrare l'analizzatore personalizzato di +input con @command{gawk} usando la funzione API @code{register_input_parser()} +(descritta pi@`u sotto). +@end enumerate + +La definizione di una struttura @code{awk_input_buf_t} @`e simile a questa: + +@example +typedef struct awk_input @{ + const char *name; /* nome file */ + int fd; /* descrittore di file */ +#define INVALID_HANDLE (-1) + void *opaque; /* area dati privata + per l'analizzatore di input */ + int (*get_record)(char **out, struct awk_input *iobuf, + int *errcode, char **rt_start, size_t *rt_len); + ssize_t (*read_func)(); + void (*close_func)(struct awk_input *iobuf); + struct stat sbuf; /* buffer per stat */ +@} awk_input_buf_t; +@end example + +I campi si possono dividere in due categorie: quelli che sono usati (almeno +inizialmente) da @code{@var{XXX}_can_take_file()}, e quelli che sono usati da +@code{@var{XXX}_take_control_of()}. Il primo gruppo di campi, e il loro uso, +@`e cos@`{@dotless{i}} definito: + +@table @code +@item const char *name; +Il nome del file. + +@item int fd; +Un descrittore di file per il file. Se @command{gawk} riesce ad aprire +il file, il valore di @code{fd} @emph{non} sar@`a uguale a +@code{INVALID_HANDLE} [descrittore non valido]. In caso contrario, +quello sar@`a il valore. + +@item struct stat sbuf; +Se il descrittore di file @`e valido, @command{gawk} avr@`a riempito i campi di +questa struttura invocando la chiamata di sistema @code{fstat()}. +@end table + +La funzione @code{@var{XXX}_can_take_file()} dovrebbe esaminare i campi di +cui sopra e decidere se l'analizzatore di input vada usato per il file. +La decisione pu@`o dipendere da uno stato di @command{gawk} (il valore +di una variabile definita in precedenza dall'estensione e impostata dal +codice @command{awk}), dal nome del +file, dal fatto che il descrittore di file sia valido o no, +dalle informazioni contenute in @code{struct stat} o da una qualsiasi +combinazione di questi fattori. + +Una volta che @code{@var{XXX}_can_take_file()} restituisce @dfn{true}, e +@command{gawk} ha deciso di usare l'analizzatore personalizzato, viene +chiamata la funzione @code{@var{XXX}_take_control_of()}. Tale funzione +si occupa di riempire il campo @code{get_record} oppure il campo +@code{read_func} nella struttura @code{awk_input_buf_t}. La funzione si +assicura inoltre che @code{fd} @emph{not} sia impostato al valore +@code{INVALID_HANDLE}. L'elenco seguente descrive i campi che +possono essere riempiti da @code{@var{XXX}_take_control_of()}: + +@table @code +@item void *opaque; +Questo campo @`e usato per contenere qualiasi informazione di stato sia +necessaria per l'analizzatore di input +riguardo a questo file. Il campo @`e ``opaco'' per @command{gawk}. +L'analizzatore di input non @`e obbligato a usare questo puntatore. + +@item int@ (*get_record)(char@ **out, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ struct@ awk_input *iobuf, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ int *errcode, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ char **rt_start, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ size_t *rt_len); +Questo puntatore a funzione dovrebbe puntare a una funzione che crea i record +in input. Tale funzione @`e il nucleo centrale dell'analizzatore di input. +Il suo modo di operare @`e descritto nel testo che segue questo elenco. + +@item ssize_t (*read_func)(); +Questo puntatore a funzione dovrebbe puntare a una funzione che ha lo +stesso comportamento della chiamata di sistema standard POSIX @code{read()}. +@`E in alternativa al puntatore a @code{get_record}. Il relativo comportamento +@`e pure descritto nel testo che segue quest'elenco. + +@item void (*close_func)(struct awk_input *iobuf); +Questo puntatore a funzione dovrebbe puntare a una funzione che fa +la ``pulizia finale''. Dovrebbe liberare ogni risorsa allocata da +@code{@var{XXX}_take_control_of()}. Pu@`o anche chiudere il file. Se lo fa, +dovrebbe impostare il campo @code{fd} a @code{INVALID_HANDLE}. + +Se @code{fd} @`e ancora diverso da @code{INVALID_HANDLE} dopo la chiamata a +questa funzione, @command{gawk} invoca la normale chiamata di sistema +@code{close()}. + +Avere una funzione di ``pulizia'' @`e facoltativo. Se l'analizzatore di input +non ne ha bisogno, basta non impostare questo campo. In questo caso, +@command{gawk} invoca la normale chiamata di sistema @code{close()} per il +descrittore di file, che, quindi, dovrebbe essere valido. +@end table + +La funzione @code{@var{XXX}_get_record()} svolge il lavoro di creazione dei +record in input. I parametri sono i seguenti: + +@table @code +@item char **out +Questo @`e un puntatore a una variabile @code{char *} che @`e impostatata in modo +da puntare al record. @command{gawk} usa una sua copia locale dei dati, +quindi l'estensione deve gestire la relativa area di memoria. + +@item struct awk_input *iobuf +Questa @`e la struttura @code{awk_input_buf_t} per il file. I campi dovrebbero +essere usati per leggere i dati (@code{fd}) e per gestire lo stato privato +(@code{opaque}), se necessario. + +@item int *errcode +Se si verifica un errore, @code{*errcode} dovrebbe essere impostato a un +valore appropriato tra quelli contenuti in @code{<errno.h>}. + +@item char **rt_start +@itemx size_t *rt_len +Se il concetto ``fine record'' @`e applicabile, +@code{*rt_start} dovrebbe essere impostato per puntare ai dati da usare come +@code{RT}, e @code{*rt_len} dovrebbe essere impostata alla lunghezza di quel +campo. In caso contrario, @code{*rt_len} dovrebbe essere impostata a zero. +@command{gawk} usa una sua copia di questi dati, quindi l'estensione deve +gestire tale memoria. +@end table + +Il codice di ritorno @`e la lunghezza del buffer puntato da +@code{*out} oppure @code{EOF}, se @`e stata raggiunta la fine del file o se +si @`e verificato un errore. + +Poich@'e @code{errcode} @`e sicuramente un puntatore valido, non c'@`e +bisogno di controllare che il valore sia @code{NULL}. @command{gawk} +imposta @code{*errcode} a zero, quindi non c'@`e bisogno di impostarlo, a meno +che non si verifichi un errore. + +In presenza di un errore, la funzione dovrebbe restituire @code{EOF} e +impostare @code{*errcode} a un valore maggiore di zero. In questo caso, se +@code{*errcode} non @`e uguale a zero, @command{gawk} automaticamente aggiorna +la variabile @code{ERRNO} usando il valore contenuto in @code{*errcode}. +(In generale, impostare @samp{*errcode = errno} dovrebbe essere la +cosa giusta da fare.) + +Invece di fornire una funzione che restituisce un record in input, +@`e possibile fornirne una che semplicemente legge dei byte, e lascia +che sia @command{gawk} ad analizzare i dati per farne dei record. In questo +caso, i dati dovrebbero essere restituiti nella codifica multibyte propria +della localizzazione corrente. +Una siffatta funzione dovrebbe imitare il comportamento della chiamata di +sistema @code{read()}, e riempire il puntatore @code{read_func} con +il proprio indirizzo nella struttura @code{awk_input_buf_t}. + +Per default, @command{gawk} imposta il puntatore @code{read_func} in modo che +punti alla chiamata di sistema @code{read()}. In questo modo l'estensione +non deve preoccuparsi di impostare esplicitamente questo campo. + +@quotation NOTA +Occorre decidere per l'uno o per l'altro metodo: o una funzione che +restituisce un record o una che restituisce dei dati grezzi. Nel dettaglio, +se si fornisce una funzione che prepara un record, @command{gawk} la +invocher@`a, e non chiamer@`a mai la funzione che fa una lettura grezza. +@end quotation + +@command{gawk} viene distribuito con un'estensione di esempio che legge +delle directory, restituendo un record per ogni elemento contenuto nella +directory (@pxref{Esempio di estensione Readdir}. Questo codice sorgente pu@`o +essere usato come modello per scrivere un analizzatore di input +personalizzato. + +Quando si scrive un analizzatore di input, si dovrebbe progettare (e +documentare) il modo con cui si suppone che interagisca con il codice +@command{awk}. Si pu@`o scegliere di utilizzarlo per tutte le letture, e +intervenire solo quando @`e necessario, (come fa l'estensione di +esempio @code{readdir}). Oppure lo si pu@`o utilizzare a seconda del +valore preso da una variabile @command{awk}, come fa l'estensione XML +inclusa nel progetto @code{gawkextlib} (@pxref{gawkextlib}). +In quest'ultimo caso, il codice in una regola @code{BEGINFILE} +pu@`o controllare @code{FILENAME} ed @code{ERRNO} per decidere se +attivare un analizzatore di input (@pxref{BEGINFILE/ENDFILE}) oppure no. + +Un analizzatore di input va registrato usando la seguente funzione: + +@table @code +@item void register_input_parser(awk_input_parser_t *input_parser); +Registra l'analizzatore di input puntato da @code{input_parser} con +@command{gawk}. +@end table + +@node Processori di output +@subsubsection Registrare un processore di output +@cindex personalizzato, processore di output +@cindex processore di output personalizzato +@cindex output, processore di, personalizzato + +@cindex processore di output +@cindex output, processore di +Un @dfn{processore di output} @`e l'immagine riflessa di un +analizzatore di input. +Consente a un'estensione di prendere il controllo dell'output +indirizzato verso un file +che sia stato aperto con gli operatori di ridirezione di I/O +@samp{>} o @samp{>>} (@pxref{Ridirezione}). + +Il processore di output @`e molto simile, come struttura, +all'analizzatore di input: + +@example +typedef struct awk_output_wrapper @{ + const char *name; /* nome del processore */ + awk_bool_t (*can_take_file)(const awk_output_buf_t *outbuf); + awk_bool_t (*take_control_of)(awk_output_buf_t *outbuf); + awk_const struct awk_output_wrapper *awk_const next; /* per gawk */ +@} awk_output_wrapper_t; +@end example + +I campi sono i seguenti: + +@table @code +@item const char *name; +Questo @`e il nome del processore di output. + +@item awk_bool_t (*can_take_file)(const awk_output_buf_t *outbuf); +Questo @`e il puntatore a una funzione che esamina l'informazione contenuta +nella struttura @code{awk_output_buf_t} puntata da @code{outbuf}. +Dovrebbe restituire @dfn{true} se il processore di output vuole elaborare +il file, e @dfn{false} in caso contrario. +Nessuno stato (valori di variabili, etc.) dovrebbe essere modificato +all'interno di @command{gawk}. + +@item awk_bool_t (*take_control_of)(awk_output_buf_t *outbuf); +La funzione puntata da questo campo viene chiamata quando @command{gawk} +decide di consentire al processore di output di prendere il controllo del file. +Dovrebbe riempire in maniera appropriata dei campi nella struttura +@code{awk_output_buf_t}, come descritto sotto, e restituire @dfn{true} se +ha successo, @dfn{false} in caso contrario. + +@item awk_const struct output_wrapper *awk_const next; +Questa struttura @`e per uso di @command{gawk}; +per questo motivo @`e marcata @code{awk_const} in modo che l'estensione non +possa modificarlo. +@end table + +La struttura @code{awk_output_buf_t} @`e simile a questa: + +@example +typedef struct awk_output_buf @{ + const char *name; /* nome del file in output */ + const char *mode; /* argomento @dfn{mode} per fopen */ + FILE *fp; /* puntatore stdio file */ + awk_bool_t redirected; /* @dfn{true} se un processore @`e attivo */ + void *opaque; /* per uso del processore di output */ + size_t (*gawk_fwrite)(const void *buf, size_t size, size_t count, + FILE *fp, void *opaque); + int (*gawk_fflush)(FILE *fp, void *opaque); + int (*gawk_ferror)(FILE *fp, void *opaque); + int (*gawk_fclose)(FILE *fp, void *opaque); +@} awk_output_buf_t; +@end example + +Anche qui, l'estensione definir@`a le funzioni @code{@var{XXX}_can_take_file()} +e @code{@var{XXX}_take_control_of()} che esaminano e aggiornano +campi dati in @code{awk_output_buf_t}. +I campi dati sono i seguenti: + +@table @code +@item const char *name; +Il nome del file in output. + +@item const char *mode; +La stringa @dfn{mode} (come sarebbe usata nel secondo argomento della +chiamata di sistema @code{fopen()}) +con cui il file era stato aperto. + +@item FILE *fp; +Il puntatore @code{FILE} da @code{<stdio.h>}. @command{gawk} apre il file +prima di controllare se esiste un processore di output. + +@item awk_bool_t redirected; +Questo campo dev'essere impostato a @dfn{true} dalla funzione +@code{@var{XXX}_take_control_of()}. + +@item void *opaque; +Questo puntatore @`e opaco per @command{gawk}. L'estensione dovrebbe usarlo +per contenere un puntatore a qualsiasi dato privato associato al file. + +@item size_t (*gawk_fwrite)(const void *buf, size_t size, size_t count, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ FILE *fp, void *opaque); +@itemx int (*gawk_fflush)(FILE *fp, void *opaque); +@itemx int (*gawk_ferror)(FILE *fp, void *opaque); +@itemx int (*gawk_fclose)(FILE *fp, void *opaque); +Questi puntatori dovrebbero essere impostati per puntare a funzioni +la cui azione sia equivalente a quella delle funzioni di @code{<stdio.h>}, +se questo @`e cio che si desidera. +@command{gawk} usa questi puntatori a funzione per @emph{tutti} gli output. +@command{gawk} inizializza i puntatori per puntare a funzioni interne +``di passaggio'' che si limitano a chiamare le funzioni normali di +@code{<stdio.h>}, e quindi un'estensione deve ridefinire solo le funzioni +appropriate per fare il lavoro richiesto. +@end table + +La funzione @code{@var{XXX}_can_take_file()} dovrebbe decidere in base ai +campi @code{name} e @code{mode}, e a ogni altro ulteriore indicatore di stato +(p.es., valori di variabili @command{awk}) adatto allo scopo. + +Quando @command{gawk} chiama @code{@var{XXX}_take_control_of()}, la funzione +dovrebbe riempire i rimanenti campi +in modo opportuno, tranne che per @code{fp}, che dovrebbe essere usato +normalmente. + +Il processore di output va registrato usando la seguente funzione: + +@table @code +@item void register_output_wrapper(awk_output_wrapper_t *output_wrapper); +Registra il processore di output puntato da @code{output_wrapper} con +@command{gawk}. +@end table + +@node Processori bidirezionali +@subsubsection Registrare un processore bidirezionale +@cindex personalizzato, processore bidirezionale +@cindex processore bidirezionale personalizzato +@cindex bidirezionale, processore personalizzato + +Un @dfn{processore bidirezionale} combina un analizzatore di input e +un processore di output per un I/O +bidirezionale usando l'operatore @samp{|&} (@pxref{Ridirezione}). +Le strutture @code{awk_input_parser_t} e @code{awk_output_buf_t} +sono usate nella maniera gi@`a descritta precedentemente. + +Un processore bidirezionale @`e rappresentato dalla struttura seguente: + +@example +typedef struct awk_two_way_processor @{ + const char *name; /* nome del processore bidirezionale */ + awk_bool_t (*can_take_two_way)(const char *name); + awk_bool_t (*take_control_of)(const char *name, + awk_input_buf_t *inbuf, + awk_output_buf_t *outbuf); + awk_const struct awk_two_way_processor *awk_const next; /* per gawk */ +@} awk_two_way_processor_t; +@end example + +I campi sono i seguenti: + +@table @code +@item const char *name; +Il nome del processore bidirezionale. + +@item awk_bool_t (*can_take_two_way)(const char *name); +La funzione puntata da questo campo dovrebbe restituire @dfn{true} se +vuole gestire l'I/O bidirezionale per questo @value{FN}. +La funzione non dovrebbe modificare alcuno stato (valori di variabili, etc.) +all'interno di @command{gawk}. + +@item awk_bool_t (*take_control_of)(const char *name, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_input_buf_t *inbuf, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_output_buf_t *outbuf); +La funzione puntata da questo campo dovrebbe riempire le strutture +@code{awk_input_buf_t} e @code{awk_output_buf_t} puntate da @code{inbuf} e +@code{outbuf}, rispettivamente. Queste strutture sono gi@`a state descritte +in precedenza. + +@item awk_const struct two_way_processor *awk_const next; +Questa struttura @`e per uso di @command{gawk}; +per questo motivo @`e marcata @code{awk_const} in modo che l'estensione non +possa modificarla. +@end table + +Come per l'analizzatore di input e il processore di output, vanno fornite le +funzione ``s@`{@dotless{i}}, ci penso io'' e ``per questo, fai tu'', +@code{@var{XXX}_can_take_two_way()} e @code{@var{XXX}_take_control_of()}. + +Il processore bidirezionale va registrato usando la seguente funzione: + +@table @code +@item void register_two_way_processor(awk_two_way_processor_t *two_way_processor); +Registra il processore bidirezionale puntato da @code{two_way_processor} con +@command{gawk}. +@end table + +@node Stampare messaggi +@subsection Stampare messaggi dalle estensioni +@cindex stampare messaggi dalle estensioni +@cindex messaggi, stampare dalle estensioni +@cindex estensioni, stampare messaggi dalle + +@`E possibile stampare diversi tipi di messaggi di avvertimento da +un'estensione, come qui spiegato. Si noti che, per queste funzioni, +si deve fornire l'ID di estensione ricevuto da @command{gawk} +al momento in cui l'estensione @`e stata caricata:@footnote{Poich@'e l'API usa solo +funzionalit@`a previste dal +compilatore ISO C 90, non @`e possibile usare le macro di tipo variadico +(che accettano un numero variabile di argomenti) disponibili nel compilatore +ISO C 99, che nasconderebbero quel parametro. Un vero peccato!} + +@table @code +@item void fatal(awk_ext_id_t id, const char *format, ...); +Stampa un messaggio e poi @command{gawk} termina immediatamente l'esecuzione. + +@item void nonfatal(awk_ext_id_t id, const char *format, ...); +Stampa un messaggio di errore non-fatale. + +@item void warning(awk_ext_id_t id, const char *format, ...); +Stampa un messaggio di avvertimento. + +@item void lintwarn(awk_ext_id_t id, const char *format, ...); +Stampa un messaggio di avvertimento ``lint''. Normalmente questo equivale a +stampare un messaggio di avvertimento, ma se @command{gawk} era stato +invocato specificando l'opzione @samp{--lint=fatal}, +gli avvertimenti di @dfn{lint} diventano messaggi di errore fatali. +@end table + +Tutte queste funzioni sono per il resto simili alla famiglia di funzioni +@code{printf()} del linguaggio C, dove il parametro @code{format} @`e una +stringa contenente dei caratteri normali e delle istruzioni di formattazione, +mischiati tra loro. + +@node Aggiornare @code{ERRNO} +@subsection Funzioni per aggiornare @code{ERRNO} + +Le seguenti funzioni consentono l'aggiornamento della variabile +@code{ERRNO}: + +@table @code +@item void update_ERRNO_int(int errno_val); +Imposta @code{ERRNO} alla stringa equivalente del codice di errore +in @code{errno_val}. Il valore dovrebbe essere uno dei codici di errore +definiti in @code{<errno.h>}, e @command{gawk} lo trasforma in una stringa +(qualora possibile, tradotta) usando la funzione C @code{strerror()}. + +@item void update_ERRNO_string(const char *string); +Imposta @code{ERRNO} direttamente usando il valore della stringa specificata. +@command{gawk} fa una copia del valore di @code{stringa}. + +@item void unset_ERRNO(void); +Annulla il valore di @code{ERRNO}. +@end table + +@node Richiedere valori +@subsection Richiedere valori + +Tutte le funzioni che restituiscono valori da @command{gawk} +funzionano allo stesso modo. Si fornisce un campo @code{awk_valtype_t} +per indicare il tipo di valore che ci si aspetta. Se il valore disponibile +corrisponde a quello richiesto, la funzione restituisce @dfn{true} e riempie +il campo del risultato @code{awk_value_t}. +Altrimenti, la funzione restituisce @dfn{false}, e il campo @code{val_type} +indica il tipo di valore disponibile. +A quel punto si pu@`o, a seconda di quel che richiede la situazione, +stampare un messaggio di errore oppure ripetere la +richiesta specificando il tipo di valore che risulta disponibile. Questo +comportamento @`e riassunto nella +@ref{table-value-types-returned}. + +@float Tabella,table-value-types-returned +@caption{Tipi di valori restituiti dall'API} +@docbook +<informaltable> +<tgroup cols="8"> + <colspec colname="c1"/> + <colspec colname="c2"/> + <colspec colname="c3"/> + <colspec colname="c4"/> + <colspec colname="c5"/> + <colspec colname="c6"/> + <colspec colname="c7"/> + <colspec colname="c8"/> + <spanspec spanname="hspan" namest="c3" nameend="c8" align="center"/> + <thead> + <row><entry></entry><entry spanname="hspan"><para>Tipo di valore reale</para></entry></row> + <row> + <entry></entry> + <entry></entry> + <entry><para>Stringa</para></entry> + <entry><para>Strnum</para></entry> + <entry><para>Numero</para></entry> + <entry><para>Regexp</para></entry> + <entry><para>Vettore</para></entry> + <entry><para>Indefinito</para></entry> + </row> + </thead> + <tbody> + <row> + <entry></entry> + <entry><para><emphasis role="bold">Stringa</emphasis></para></entry> + <entry><para>Stringa</para></entry> + <entry><para>Stringa</para></entry> + <entry><para>Stringa</para></entry> + <entry><para>Stringa</para></entry> + <entry><para>false</para></entry> + <entry><para>false</para></entry> + </row> + <row> + <entry></entry> + <entry><para><emphasis role="bold">Strnum</emphasis></para></entry> + <entry><para>false</para></entry> + <entry><para>Strnum</para></entry> + <entry><para>Strnum</para></entry> + <entry><para>false</para></entry> + <entry><para>false</para></entry> + <entry><para>false</para></entry> + </row> + <row> + <entry></entry> + <entry><para><emphasis role="bold">Numero</emphasis></para></entry> + <entry><para>Numero</para></entry> + <entry><para>Numero</para></entry> + <entry><para>Numero</para></entry> + <entry><para>false</para></entry> + <entry><para>false</para></entry> + <entry><para>false</para></entry> + </row> + <row> + <entry><para><emphasis role="bold">Tipo</emphasis></para></entry> + <entry><para><emphasis role="bold">Regexp</emphasis></para></entry> + <entry><para>false</para></entry> + <entry><para>false</para></entry> + <entry><para>Regexp</para></entry> + <entry><para>false</para></entry> + <entry><para>false</para></entry> + <entry><para>false</para></entry> + </row> + <row> + <entry><para><emphasis role="bold">Richiesto</emphasis></para></entry> + <entry><para><emphasis role="bold">Vettore</emphasis></para></entry> + <entry><para>false</para></entry> + <entry><para>false</para></entry> + <entry><para>false</para></entry> + <entry><para>false</para></entry> + <entry><para>Vettore</para></entry> + <entry><para>false</para></entry> + </row> + <row> + <entry></entry> + <entry><para><emphasis role="bold">Scalare</emphasis></para></entry> + <entry><para>Scalare</para></entry> + <entry><para>Scalare</para></entry> + <entry><para>Scalare</para></entry> + <entry><para>Scalare</para></entry> + <entry><para>false</para></entry> + <entry><para>false</para></entry> + </row> + <row> + <entry></entry> + <entry><para><emphasis role="bold">Indefinito</emphasis></para></entry> + <entry><para>Stringa</para></entry> + <entry><para>Strnum</para></entry> + <entry><para>Numero</para></entry> + <entry><para>Regexp</para></entry> + <entry><para>Vettore</para></entry> + <entry><para>Indefinito</para></entry> + </row> + <row> + <entry></entry> + <entry><para><emphasis role="bold">@dfn{Value cookie}</emphasis></para></entry> + <entry><para>false</para></entry> + <entry><para>false</para></entry> + <entry><para>false</para></entry> + <entry><para>false</para></entry> + <entry><para>false</para></entry> + <entry><para>false</para></entry> + </row> + </tbody> +</tgroup> +</informaltable> +@end docbook + +@ifnotplaintext +@ifnotdocbook +@multitable @columnfractions .50 .50 +@headitem @tab Tipo di valore reale +@end multitable +@c 10/2014: Thanks to Karl Berry for this bit to reduce the space: +@tex +\vglue-1.1\baselineskip +@end tex +@c @multitable @columnfractions .166 .166 .198 .15 .15 .166 +@ifclear SMALLPRINT +@multitable {Richiesto} {Indefinito} {Numero} {Numero} {Scalar} {Regexp} {Vettore} {Indefinito} +@headitem @tab @tab Stringa @tab Strnum @tab Numero @tab Regexp @tab Vettore @tab Indefinito +@item @tab @b{Stringa} @tab Stringa @tab Stringa @tab Stringa @tab Stringa @tab false @tab false +@item @tab @b{Strnum} @tab false @tab Strnum @tab Strnum @tab false @tab false @tab false +@item @tab @b{Numero} @tab Numero @tab Numero @tab Numero @tab false @tab false @tab false +@item @b{Tipo} @tab @b{Regexp} @tab false @tab false @tab false @tab Regexp @tab false @tab false +@item @b{Richiesto} @tab @b{Vettore} @tab false @tab false @tab false @tab false @tab Vettore @tab false +@item @tab @b{Scalar} @tab Scalar @tab Scalar @tab Scalar @tab Scalar @tab false @tab false +@item @tab @b{Indefinito} @tab Stringa @tab Strnum @tab Numero @tab Regexp @tab Vettore @tab Indefinito +@item @tab @b{Value cookie} @tab false @tab false @tab false @tab false @tab false @tab false +@end multitable +@end ifclear + +@ifset SMALLPRINT +@smallformat +@multitable {Richiesto} {Value cookie} {Num.} {Num.} {Scal.} {Regexp} {Vett.} {Indef.} +@headitem @tab @tab String @tab Strn. @tab Num. @tab Regexp @tab Vett. @tab Indef. +@item @tab @b{Stringa} @tab String @tab String @tab String @tab String @tab false @tab false +@item @tab @b{Strnum} @tab false @tab Strn. @tab Strn. @tab false @tab false @tab false +@item @tab @b{Numero} @tab Num. @tab Num. @tab Num. @tab false @tab false @tab false +@item @b{Tipo} @tab @b{Regexp} @tab false @tab false @tab false @tab Regexp @tab false @tab false +@item @b{Richiesto} @tab @b{Vettore} @tab false @tab false @tab false @tab false @tab Vett. @tab false +@item @tab @b{Scalar} @tab Scal. @tab Scal. @tab Scal. @tab Scal. @tab false @tab false +@item @tab @b{Indefinito} @tab String @tab Strn. @tab Num. @tab Regexp @tab Vett. @tab Indef. +@item @tab @b{Value cookie} @tab false @tab false @tab false @tab false @tab false @tab false +@end multitable +@end smallformat +@end ifset +@end ifnotdocbook +@end ifnotplaintext +@ifplaintext +@verbatim + +-------------------------------------------------------+ + | Tipo di valore reale: | + +--------+--------+--------+--------+-------+-----------+ + | Stringa| Strnum | Numero | Regexp |Vettore| Indefinito| ++-----------+-----------+--------+--------+--------+--------+-------+-----------+ +| | Stringa | Stringa| Stringa| Stringa| Stringa| false | false | +| +-----------+--------+--------+--------+--------+-------+-----------+ +| | Strnum | false | Strnum | Strnum | false | false | false | +| +-----------+--------+--------+--------+--------+-------+-----------+ +| | Numero | Numero | Numero | Numero | false | false | false | +| +-----------+--------+--------+--------+--------+-------+-----------+ +| | Regexp | false | false | false | Regexp | false | false | +| Tipo +-----------+--------+--------+--------+--------+-------+-----------+ +|Richiesto: | Vettore | false | false | false | false |Vettore| false | +| +-----------+--------+--------+--------+--------+-------+-----------+ +| | Scalare | Scalare| Scalare| Scalare| Scalare| false | false | +| +-----------+--------+--------+--------+--------+-------+-----------+ +| | Indefinito| Stringa| Strnum | Numero | Regexp |Vettore| Indefinito| +| +-----------+--------+--------+--------+--------+-------+-----------+ +| | Value- | false | false | false | false | false | false | +| | Cookie | | | | | | | ++-----------+-----------+--------+--------+--------+--------+-------+-----------+ +@end verbatim +@end ifplaintext +@end float + +@node Accedere ai parametri +@subsection Accedere ai parametri e aggiornarli + +Due funzioni consentono di accedere agli argomenti (parametri) +passati all'estensione. Esse sono: + +@table @code +@item awk_bool_t get_argument(size_t count, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_valtype_t wanted, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_value_t *risultato); +Riempie la struttura @code{awk_value_t} puntata da @code{risultato} +con l'argomento numero @code{count}. Restituisce @dfn{true} se il tipo +dell'argomento corrisponde +a quello specificato in @code{wanted}, e @dfn{false} in caso contrario. +In quest'ultimo caso, +@code{risultato@w{->}val_type} indica il tipo effettivo dell'argomento +(@pxref{table-value-types-returned}). La numerazione degli argomenti parte +da zero: il primo +argomento @`e il numero zero, il secondo @`e il numero uno, e cos@`{@dotless{i}} via. +@code{wanted} indica il tipo di valore atteso. + +@item awk_bool_t set_argument(size_t count, awk_array_t array); +Converte un parametro di tipo indefinito in un vettore; ci@`o permette la +chiamata per riferimento per i vettori. Restituisce @dfn{false} se @code{count} @`e troppo elevato, +o se il tipo di argomento @`e diverso da @dfn{undefined}. +@xref{Manipolazione di vettori} +per ulteriori informazioni riguardo alla creazione di vettori. +@end table + +@node Accedere alla tabella simboli +@subsection Accedere alla Tabella dei simboli +@cindex accedere alle variabili globali dalle estensioni +@cindex variabili globali, accesso dalle estensioni +@cindex estensioni, accesso alle variabili globali + +Due insiemi di routine permettono di accedere alle variabili globali, +e un insieme consente di creare e rilasciare dei valori nascosti. + +@menu +* Tabella simboli per nome:: Accedere alle variabili per nome. +* Tabella simboli tramite cookie:: Accedere alle variabili per ``cookie''. +* Valori nascosti:: Creare e usare valori nascosti. +@end menu + +@node Tabella simboli per nome +@subsubsection Accedere alle variabili per nome e aggiornarle + +Le routine che seguono permettono di raggiungere e aggiornare +le variabili globali a livello di @command{awk} per nome. Nel gergo dei +compilatori, gli identificativi di vario tipo sono noti come @dfn{simboli}, +da cui il prefisso ``sym'' nei nomi delle routine. La struttura di dati che +contiene informazioni sui simboli @`e chiamata @dfn{Tabella dei simboli} +(@dfn{Symbol table}). +Le funzioni sono le seguenti: + +@table @code +@item awk_bool_t sym_lookup(const char *name, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_valtype_t wanted, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_value_t *risultato); +Riempie la struttura @code{awk_value_t} puntata da @code{risultato} +con il valore della variabile il cui nome @`e nella stringa @code{name}, +che @`e una normale stringa di caratteri C. +@code{wanted} indica il tipo di valore atteso. +La funzione restituisce @dfn{true} se il tipo effettivo della variabile @`e quello +specificato in @code{wanted}, e @dfn{false} in caso contrario. +In quest'ultimo caso, @code{risultato>val_type} indica il tipo effettivo +della variabile +(@pxref{table-value-types-returned}). + +@item awk_bool_t sym_update(const char *name, awk_value_t *valore); +Aggiorna la variabile il cui nome @`e contenuto nella stringa @code{name}, +che @`e una normale stringa di caratteri C. +La variabile @`e aggiunta alla Tabella dei simboli di @command{gawk}, +se non @`e gi@`a presente. Restituisce @dfn{true} se tutto @`e andato bene, e +@dfn{false} in caso contrario. + +La modifica del tipo (da scalare a vettoriale o viceversa) di una variabile +gi@`a esistente @emph{non} @`e consentito, e questa routine non pu@`o neppure +essere usata per aggiornare un vettore. +Questa routine non pu@`o essere usata per modificare nessuna delle variabili +predefinite (come @code{ARGC} o @code{NF}). +@end table + +Un'estensione pu@`o andare a cercare il valore delle variabili speciali di +@command{gawk}. +Tuttavia, con l'eccezione del vettore @code{PROCINFO}, un'estensione +non pu@`o cambiare alcuna di queste variabili. + +@node Tabella simboli tramite cookie +@subsubsection Accedere alle variabili per ``cookie'' e aggiornarle + +Uno @dfn{scalar cookie} @`e un puntatore nascosto (@dfn{opaque handle}) che +fornisce accesso a una +variabile globale o a un vettore. Si tratta di un'ottimizzazione, per evitare +di ricercare variabili nella Tabella dei simboli di @command{gawk} ogni volta +che un accesso @`e necessario. Questo +argomento @`e gi@`a stato trattato in precedenza, nella +@ref{Tipi di dati generali}. + +Le funzioni seguenti servono per gestire gli @dfn{scalar cookie}: + +@table @code +@item awk_bool_t sym_lookup_scalar(awk_scalar_t cookie, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_valtype_t wanted, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_value_t *risultato); +Ottiene il valore corrente di uno @dfn{scalar cookie}. +Una volta ottenuto lo @dfn{scalar cookie} usando @code{sym_lookup()}, si +pu@`o usare questa funzione per accedere al valore della variabile in modo +pi@`u efficiente. +Restituisce @dfn{false} se il valore non @`e disponibile. + +@item awk_bool_t sym_update_scalar(awk_scalar_t cookie, awk_value_t *valore); +Aggiorna il valore associato con uno @dfn{scalar cookie}. +Restituisce @dfn{false} se il nuovo valore non @`e del tipo +@code{AWK_STRING}, @code{AWK_STRNUM}, @code{AWK_REGEX} o @code{AWK_NUMBER}. +Anche in questo caso, le variabili predefinite non possono essere aggiornate. +@end table + +Non @`e immediatamente evidente come si lavora con gli @dfn{scalar cookie} o +quale sia la loro vera @i{ragion d'essere}. In teoria, le routine +@code{sym_lookup()} e @code{sym_update()} sono tutto ci@`o che occorre per +lavorare con le variabili. Per esempio, ci potrebbe essere un codice che +ricerca il valore di una variabile, valuta una condizione, e potrebbe +poi cambiare il valore della variabile a seconda dei risultati della +valutazione in modo simile a questo: + +@example +/* do_magic --- fai qualcosa di veramente grande */ + +static awk_value_t * +do_magic(int nargs, awk_value_t *risultato) +@{ + awk_value_t valore; + + if ( sym_lookup("MAGIC_VAR", AWK_NUMBER, & valore) + && qualche_condizione(valore.num_valore)) @{ + valore.num_valore += 42; + sym_update("MAGIC_VAR", & valore); + @} + + return make_number(0.0, risultato); +@} +@end example + +@noindent +Questo codice sembra (ed @`e) semplice e immediato. Qual @`e il problema? + +Beh, si consideri cosa succede se un qualche codice a livello di @command{awk} +associato con l'estensione richiama la funzione @code{magic()} +(implementata in linguaggio C da @code{do_magic()}), una volta per ogni +record, mentre si stanno elaborando +file contenenti migliaia o milioni di record. +La variabile @code{MAGIC_VAR} viene ricercata nella Tabella dei simboli una o due +volte per ogni richiamo della funzione! + +La ricerca all'interno della Tabella dei simboli @`e in realt@`a una pura perdita +di tempo; @`e molto pi@`u efficiente +ottenere un @dfn{value cookie} che rappresenta la variabile, e usarlo per +ottenere il valore della variabile e aggiornarlo a seconda della +necessit@`a.@footnote{La differenza @`e misurabile e indubbiamente reale. +Fidatevi.} + +Quindi, la maniera per usare i valori-cookie @`e la seguente. Per prima +cosa, la variabile di estensione va messa nella Tabella dei simboli di +@command{gawk} usando @code{sym_update()}, come al solito. Poi si deve ottenere +uno @dfn{scalar cookie} per la +variabile usando @code{sym_lookup()}: + +@example +static awk_scalar_t magic_var_cookie; /* cookie per MAGIC_VAR */ + +static void +inizializza_estensione() +@{ + awk_value_t valore; + + /* immettere il valore iniziale */ + sym_update("MAGIC_VAR", make_number(42.0, & valore)); + + /* ottenere il @dfn{value cookie} */ + sym_lookup("MAGIC_VAR", AWK_SCALAR, & valore); + + /* salvarlo per dopo */ + magic_var_cookie = valore.scalar_cookie; + @dots{} +@} +@end example + +Dopo aver fatto questo, si usino le routine descritte in questa @value{SECTION} +per ottenere e modificare +il valore usando il @dfn{value cookie}. Quindi, @code{do_magic()} diviene ora +qualcosa del tipo: + +@example +/* do_magic --- fai qualcosa di veramente grande */ + +static awk_value_t * +do_magic(int nargs, awk_value_t *risultato) +@{ + awk_value_t valore; + + if ( sym_lookup_scalar(magic_var_cookie, AWK_NUMBER, & valore) + && qualche_condizione(valore.num_valore)) @{ + valore.num_valore += 42; + sym_update_scalar(magic_var_cookie, & valore); + @} + @dots{} + + return make_number(0.0, risultato); +@} +@end example + +@quotation NOTA +Il codice appena visto omette il controllo di eventuali errori, per +amor di semplicit@`a. Il codice dell'estensione dovrebbe essere pi@`u complesso +e controllare attentamente i valori +restituiti dalle funzioni dell'API. +@end quotation + +@node Valori nascosti +@subsubsection Creare e usare valori nascosti + +Le routine in questa @value{SECTION} permettono di creare e rilasciare +valori nascosti. Come gli @dfn{scalar cookie}, in teoria i valori nascosti +non sono necessari. Si possono creare numeri e stringhe usando +le funzioni descritte +@iftex +nella +@end iftex +@ifnottex +in +@end ifnottex +@ref{Funzioni di costruzione}. Si possono poi assegnare +quei valori a delle variabili usando @code{sym_update()} +o @code{sym_update_scalar()}, come si preferisce. + +Tuttavia, si pu@`o comprendere l'utilit@`a di avere dei valori nascosti +se si pone mente al fatto che la memoria di @emph{ogni} valore di stringa +@emph{deve} essere ottenuta tramite @code{gawk_malloc()}, +@code{gawk_calloc()} o @code{gawk_realloc()}. +Se ci sono 20 variabili, e tutte hanno per valore la stessa stringa, +si devono creare 20 copie identiche della stringa.@footnote{I valori +numerici creano molti meno problemi, in quanto richiedono solo una variabile +C @code{double} (8 byte) per contenerli.} + +Chiaramente @`e pi@`u efficiente, se possibile, creare il valore una sola volta, +e fare in modo che @command{gawk} utilizzi quell'unico valore per molte +variabili. Questo @`e ci@`o che la routine in +@ifnotinfo +questa +@end ifnotinfo +@ifinfo +questo +@end ifinfo +@value{SECTION} permette +di fare. Le funzioni sono le seguenti: + +@table @code +@item awk_bool_t create_value(awk_value_t *valore, awk_value_cookie_t *risultato); +Crea una stringa o un valore numerico nascosti, da @code{valore}, in +vista di un successivo assegnamento di valore. Sono consentiti solo valori di +tipo @code{AWK_NUMBER}, @code{AWK_REGEX} ed @code{AWK_STRING}. +Ogni altro tipo @`e rifiutato. +Il tipo @code{AWK_UNDEFINED} potrebbe essere consentito, ma in questo caso +l'efficienza del programma ne soffrirebbe. + +@item awk_bool_t release_value(awk_value_cookie_t vc); +Libera la memoria associata con un @dfn{value cookie} ottenuto mediante +@code{create_value()}. +@end table + +Si usano i @dfn{value cookie} in modo dimile a quello con cui si usano gli +@dfn{scalar cookie}. +Nella routine di inizializzazione dell'estensione, si crea il +@dfn{value cookie}: + +@example +static awk_value_cookie_t answer_cookie; /* static @dfn{value cookie} */ + +static void +inizializza_estensione() +@{ + awk_value_t value; + char *long_string; + size_t long_string_len; + + /* codice precedente */ + @dots{} + /* @dots{} riempire long_string e long_string_len @dots{} */ + make_malloced_string(long_string, long_string_len, & value); + create_value(& value, & answer_cookie); /* creare cookie */ + @dots{} +@} +@end example + +Una volta che il valore @`e creato, si pu@`o usare come valore per un numero +qualsiasi di variabili: + +@example +static awk_value_t * +do_magic(int nargs, awk_value_t *risultato) +@{ + awk_value_t new_value; + + @dots{} /* come in precedenza */ + + value.val_type = AWK_VALUE_COOKIE; + value.value_cookie = answer_cookie; + sym_update("VAR1", & value); + sym_update("VAR2", & value); + @dots{} + sym_update("VAR100", & value); + @dots{} +@} +@end example + +@noindent +Usare @dfn{value cookie} in questo modo permette di risparmiare parecchia +memoria, poich@'e tutte le variabili da @code{VAR1} a @code{VAR100} condividono +lo stesso valore. + +Ci si potrebbe chiedere, ``Questa condivisione crea problemi? +Cosa succede se il codice @command{awk} assegna un nuovo valore a @code{VAR1}; +sono modificate anche tutte le altre variabili?'' + +Buona domanda! La risposta @`e che no, non @`e un problema. +Internamente, @command{gawk} usa +@dfn{un contatore dei riferimenti alle stringhe}. Questo significa +che molte variabili possono condividere lo stesso valore di tipo stringa, +e @command{gawk} mantiene traccia del loro uso. Quando il valore di +una variabile viene modificato, @command{gawk} semplicemente diminuisce di +uno il contatore dei riferimenti del vecchio valore, e aggiorna la variabile +perch@'e usi il nuovo valore. + +Infine, come parte della pulizia al termine del programma +(@pxref{Funzioni di exit callback}) +si deve liberare ogni valore nascosto che era stato creato, usando +la funzione @code{release_value()}. + +@node Manipolazione di vettori +@subsection Manipolazione di vettori +@cindex vettori, manipolazione nelle estensioni +@cindex estensioni, manipolazione di vettori + +La struttura di dati primaria@footnote{D'accordo, l'unica struttura di dati.} +in @command{awk} @`e il vettore associativo +@iftex +(@pxrefil{Vettori}). +@end iftex +@ifnottex +(@pxref{Vettori}). +@end ifnottex +Le estensioni devono essere in grado di manipolare vettori @command{awk}. +L'API fornisce varie strutture di dati per lavorare con vettori, +funzioni per lavorare con singoli elementi di un vettore, e funzioni per +lavorare con interi vettori. @`E prevista anche la possibilit@`a di +``appiattire'' un vettore in modo da rendere facile a un programma scritto in +C la ``visita'' di tutti gli elementi del vettore. +Le strutture dati per i vettori sono facilmente integrabili con le +strutture dati per variabili scalari, per facilitare sia l'elaborazione, sia +la creazione di @dfn{veri} vettori di vettori (@pxref{Tipi di dati generali}). + +@menu +* Tipi di dati per i vettori:: Tipi dati per lavorare coi vettori. +* Funzioni per i vettori:: Funzioni per lavorare coi vettori. +* Appiattimento di vettori:: Come appiattire i vettori. +* Creazione di vettori:: Come creare e popolare vettori. +@end menu + +@node Tipi di dati per i vettori +@subsubsection Tipi di dati per i vettori + +I tipi di dato associati con i vettori sono i seguenti: + +@table @code +@item typedef void *awk_array_t; +Se si richiede il valore di una variabile contenuta in un vettore, si ottiene +un valore del tipo @code{awk_array_t}. Questo valore @`e +@dfn{opaco}@footnote{@`E anche un +``cookie,'' ma gli sviluppatori di @command{gawk} hanno preferito non abusare +di questo termine.} per l'estensione; identifica in maniera univoca il +vettore ma pu@`o solo essere usato come parametro di una funzione dell'API, +o essere ricevuto da una funzione dell'API. Questo @`e molto simile al modo +in cui i valori @samp{FILE *} sono usati con le routine di libreria di +@code{<stdio.h>}. + +@item typedef struct awk_element @{ +@itemx @ @ @ @ /* puntatore di servizio +@itemx @ @ @ @ a lista collegata, non usato da gawk */ +@itemx @ @ @ @ struct awk_element *next; +@itemx @ @ @ @ enum @{ +@itemx @ @ @ @ @ @ @ @ AWK_ELEMENT_DEFAULT = 0,@ @ /* impostato da gawk */ +@itemx @ @ @ @ @ @ @ @ AWK_ELEMENT_DELETE = 1@ @ @ @ /* impostato dall'estensione */ +@itemx @ @ @ @ @} flags; +@itemx @ @ @ @ awk_value_t index; +@itemx @ @ @ @ awk_value_t value; +@itemx @} awk_element_t; +@code{awk_element_t} @`e un elemento di vettore ``appiattito''. +@command{awk} produce un vettore di questo tipo all'interno della struttura +@code{awk_flat_array_t} (si veda poco pi@`u avanti). +Singoli elementi di vettore possono essere marcati per essere cancellati. +Nuovi elementi del vettore devono essere aggiunti individualmente, uno per +volta, usando una funzione API apposita. I campi sono i seguenti: + +@c nested table +@table @code +@item struct awk_element *next; +Questo puntatore @`e presente come ausilio a chi scrive un'estensione. +Permette a un'estensione di creare una lista collegata (@dfn{linked list}) di +nuovi elementi che possono essere aggiunti a un vettore con un +singolo ciclo che percorre tutta la lista. + +@item enum @{ @dots{} @} flags; +Un insieme di valori di flag che passano informazione tra l'estensione +e @command{gawk}. Per ora c'@`e solo un flag disponibile: +@code{AWK_ELEMENT_DELETE}. +Se lo si imposta, @command{gawk} elimina l'elemento in questione dal vettore +originale, dopo che il vettore ``appiattito'' @`e stato rilasciato. + +@item index +@itemx value +L'indice e il valore di un elemento, rispettivamente. +@emph{Tutta} la memoria puntata da @code{index} e @code{valore} appartiene +a @command{gawk}. +@end table + +@item typedef struct awk_flat_array @{ +@itemx @ @ @ @ awk_const void *awk_const opaque1;@ @ @ @ /* per uso di gawk */ +@itemx @ @ @ @ awk_const void *awk_const opaque2;@ @ @ @ /* per uso di gawk */ +@itemx @ @ @ @ awk_const size_t count;@ @ @ @ @ /* quanti elementi nel vettore */ +@itemx @ @ @ @ awk_element_t elements[1];@ @ /* saranno ``appiattiti'' */ +@itemx @} awk_flat_array_t; +Questo @`e un vettore appiattito. Quando un'estensione ottiene da +@command{gawk} questa struttura, il vettore @code{elements} ha una dimensione +reale di @code{count} elementi. +I puntatori @code{opaque1} e @code{opaque2} sono per uso di @command{gawk}; +come tali, sono marcati come @code{awk_const} in modo che l'estensione non +possa modificarli. +@end table + +@node Funzioni per i vettori +@subsubsection Funzioni per lavorare coi vettori + +Le funzioni seguenti permettono di gestire singoli elementi di un vettore: + +@table @code +@item awk_bool_t get_element_count(awk_array_t a_cookie, size_t *count); +Per il vettore rappresentato da @code{a_cookie}, restituisce in @code{*count} +il numero di elementi in esso contenuti. Ogni sottovettore @`e conteggiato come +se fosse un solo elemento. +Restituisce @dfn{false} se si verifica un errore. + +@item awk_bool_t get_array_element(awk_array_t a_cookie, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const awk_value_t *const index, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_valtype_t wanted, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_value_t *risultato); +Per il vettore rappresentato da @code{a_cookie}, restituisce in @code{*risultato} +il valore dell'elemento il cui indice @`e @code{index}. +@code{wanted} specifica il tipo di valore che si vuole ritrovare. +Restituisce @dfn{false} se @code{wanted} non coincide con il tipo di dato o +se @code{index} non @`e nel vettore (@pxref{table-value-types-returned}). + +Il valore per @code{index} pu@`o essere numerico, nel qual caso @command{gawk} +lo converte in una stringa. Usare valori non interi @`e possibile, ma +richiede di comprendere il modo con cui tali valori sono convertiti in stringhe +(@pxref{Conversione}); per questo motivo, @`e meglio usare numeri interi. + +Come per @emph{tutte} le stringhe passate a @command{gawk} da +un'estensione, la memoria che contiene il valore della stringa con chiave +@code{index} deve essere stata acquisita utilizzando le funzioni +@code{gawk_malloc()}, @code{gawk_calloc()} o @code{gawk_realloc()}, e +@command{gawk} rilascer@`a (al momento opportuno) la relativa memoria. + +@item awk_bool_t set_array_element(awk_array_t a_cookie, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const@ awk_value_t *const index, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const@ awk_value_t *const value); +Nel vettore rappresentato da @code{a_cookie}, crea o modifica +l'elemento il cui indice @`e contenuto in @code{index}. +I vettori @code{ARGV} ed @code{ENVIRON} non possono essere modificati, +mentre il vettore @code{PROCINFO} @`e modificabile. + +@item awk_bool_t set_array_element_by_elem(awk_array_t a_cookie, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_element_t element); +Come @code{set_array_element()}, ma prende l'indice @code{index} e +il valore @code{value} da @code{element}. Questa @`e una macro di utilit@`a. + +@item awk_bool_t del_array_element(awk_array_t a_cookie, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const awk_value_t* const index); +Elimina dal vettore, rappresentato da @code{a_cookie}, l'elemento con +l'indice specificato. +Restituisce @dfn{true} se l'elemento @`e stato rimosso o @dfn{false} se +l'elemento non era presente nel vettore. +@end table + +Le seguenti funzioni operano sull'intero vettore: + +@table @code +@item awk_array_t create_array(void); +Crea un nuovo vettore a cui si possono aggiungere elementi. +@xref{Creazione di vettori} per una trattazione su come +creare un nuovo vettore e aggiungervi elementi. + +@item awk_bool_t clear_array(awk_array_t a_cookie); +Svuota il vettore rappresentato da @code{a_cookie}. +Restituisce @dfn{false} in presenza di qualche tipo di problema, @dfn{true} +in caso contrario. Il vettore non viene eliminato ma, dopo aver chiamato +questa funzione, resta privo di elementi. Questo @`e equivalente a usare +l'istruzione @code{delete} (@pxref{Cancellazione}). + +@item awk_bool_t flatten_array_typed(awk_array_t a_cookie, awk_flat_array_t **data, awk_valtype_t index_type, awk_valtype_t value_type); +Per il vettore rappresentato da @code{a_cookie}, crea una struttura +@code{awk_flat_array_t} e la riempie con indici e valori del tipo richiesto. +Imposta il puntatore il cui indirizzo @`e passato in @code{data} per puntare a +questa struttura. +Restituisce @dfn{true} se tutto va bene o @dfn{false} in caso contrario. +@ifset FOR_PRINT +Si veda la prossima @value{SECTION} +@end ifset +@ifclear FOR_PRINT +@xref{Appiattimento di vettori}, +@end ifclear +per una trattazione su come appiattire un vettore per poterci lavorare. + +@item awk_bool_t flatten_array(awk_array_t a_cookie, awk_flat_array_t **data); +Per il vettore rappresentato da @code{a_cookie}, crea una struttura +@code{awk_flat_array_t} e la riempie con indici di tipo @code{AWK_STRING} e +valori @code{AWK_UNDEFINED}. +Questa funzione @`e resa obsoleta da @code{flatten_array_typed()}. +@`E fornita come macro, e mantenuta per convenienza e per compatibilit@`a a +livello di codice sorgente con la precedente versione dell'API. + +@item awk_bool_t release_flattened_array(awk_array_t a_cookie, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_flat_array_t *data); +Quando si @`e finito di lavorare con un vettore appiattito, si liberi la +memoria usando questa funzione. Occorre fornire sia il cookie del vettore +originale, sia l'indirizzo della struttura da liberare, +@code{awk_flat_array_t}. +La funzione restituisce @dfn{true} se tutto va bene, @dfn{false} in caso contrario. +@end table + +@node Appiattimento di vettori +@subsubsection Lavorare con tutti gli elementi di un vettore + +@dfn{Appiattire} un vettore vuol dire creare una struttura che +rappresenta l'intero vettore in modo da facilitare la visita +dell'intero vettore da parte del codice in C . Parte del codice in +@file{extension/testext.c} fa questo, ed @`e anche un bell'esempio +di come utilizzare l'API. + +Questa parte del codice sorgente sar@`a descritta un po' per volta. +Ecco, per iniziare, lo script @command{gawk} che richiama l'estensione di test: + +@example +@@load "testext" +BEGIN @{ + n = split("blacky rusty sophie raincloud lucky", pets) + printf("pets ha %d elementi\n", length(pets)) + ret = dump_array_and_delete("pets", "3") + printf("dump_array_and_delete(pets) ha restituito %d\n", ret) + if ("3" in pets) + printf("dump_array_and_delete() NON ha rimosso l'indice \"3\"!\n") + else + printf("dump_array_and_delete() ha rimosso l'indice \"3\"!\n") + print "" +@} +@end example + +@noindent +Questo codice crea un vettore usando la funzione @code{split()} +(@pxref{Funzioni per stringhe}) +e poi chiama @code{dump_array_and_delete()}. Questa funzione ricerca +il vettore il cui nome @`e passato come primo argomento, ed +elimina l'elemento il cui indice @`e passato come secondo argomento. +Il codice @command{awk} stampa poi il valore restituito e controlla che +l'elemento sia stato effettivamente cancellato. Ecco il codice C che +costituisce la funzione +@code{dump_array_and_delete()}. @`E stato leggermente modificato per facilitare +l'esposizione. + +La prima parte dichiara variabili, imposta il valore di ritorno di default +in @code{risultato}, e controlla che la funzione +sia stata chiamata con il numero corretto di argomenti: + +@example +static awk_value_t * +dump_array_and_delete(int nargs, awk_value_t *risultato) +@{ + awk_value_t valore, valore2, valore3; + awk_flat_array_t *flat_array; + size_t count; + char *name; + int i; + + assert(risultato != NULL); + make_number(0.0, risultato); + + if (nargs != 2) @{ + printf("dump_array_and_delete: nargs errato " + "(%d dovrebbe essere 2)\n", nargs); + goto out; + @} +@end example + +La funzione poi prosegue un passo per volta, come segue. Il primo passo @`e +ricuperare il nome del vettore, passato come primo argomento, seguito dal +vettore stesso. Se una di queste operazioni non riesce, viene stampato un +messaggio di errore e si ritorna al chiamante: + +@example + /* trasforma in un vettore piatto il vettore + passato come argomento e lo stampa */ + if (get_argument(0, AWK_STRING, & value)) @{ + name = valore.str_value.str; + if (sym_lookup(name, AWK_array, & value2)) + printf("dump_array_and_delete: sym_lookup di %s effettuato\n", + name); + else @{ + printf("dump_array_and_delete: sym_lookup di %s non riuscito\n", + name); + goto out; + @} + @} else @{ + printf("dump_array_and_delete: get_argument(0) non riuscito\n"); + goto out; + @} +@end example + +Per controllo, e per assicurarsi che il codice C veda +lo stesso numero di elementi del codice @command{awk}, +il secondo passo @`e quello di ottenere il numero di elementi nel vettore +e stamparlo: + +@example + if (! get_element_count(valore2.array_cookie, & count)) @{ + printf("dump_array_and_delete: get_element_count non riuscito\n"); + goto out; + @} + + printf("dump_array_and_delete: il vettore in input ha %lu elementi\n", + (unsigned long) count); +@end example + +Il terzo passo @`e quello di appiattire il vettore, e quindi +controllare che il numero di elementi nella struttura @code{awk_flat_array_t} +sia uguale a quello appena trovato: + +@example + if (! flatten_array_typed(valore2.array_cookie, & flat_array, + AWK_STRING, AWK_UNDEFINED)) @{ + printf("dump_array_and_delete: non sono riuscito ad appiattire \ +il vettore\n"); + goto out; + @} + + if (flat_array->count != count) @{ + printf("dump_array_and_delete: flat_array->count (%lu)" + " != count (%lu)\n", + (unsigned long) flat_array->count, + (unsigned long) count); + goto out; + @} +@end example + +Il quarto passo @`e ritrovare l'indice dell'elemento +da eliminare, che era stato passato come secondo argomento. +Va tenuto presente che i contatori di argomenti passati a @code{get_argument()} +partono da zero, e che quindi il secondo argomento @`e quello numero uno: + +@example + if (! get_argument(1, AWK_STRING, & value3)) @{ + printf("dump_array_and_delete: get_argument(1) non riuscito\n"); + goto out; + @} +@end example + +Il quinto passo @`e quello in cui si fa il ``vero lavoro''. La funzione esegue +un ciclo su ogni elemento nel vettore, stampando i valori degli indici e +degli elementi. Inoltre, dopo aver trovato, tramite l'indice, l'elemento +che si vorrebbe eliminare, la funzione imposta il @dfn{bit} +@code{AWK_ELEMENT_DELETE} nel campo @code{flags} +dell'elemento. Quando il vettore @`e stato interamente percorso, @command{gawk} +visita il vettore appiattito, ed elimina ogni elemento in cui il relativo +@dfn{bit} della flag sia impostato: + +@example + for (i = 0; i < flat_array->count; i++) @{ + printf("\t%s[\"%.*s\"] = %s\n", + name, + (int) flat_array->elements[i].index.str_value.len, + flat_array->elements[i].index.str_value.str, + valrep2str(& flat_array->elements[i].valore)); + + if (strcmp(valore3.str_value.str, + flat_array->elements[i].index.str_value.str) == 0) @{ + flat_array->elements[i].flags |= AWK_ELEMENT_DELETE; + printf("dump_array_and_delete: ho marcato l'elemento \"%s\" " + "per eliminazione\n", + flat_array->elements[i].index.str_value.str); + @} + @} +@end example + +Il sesto passo @`e liberare il vettore appiattito. Questo segnala a +@command{gawk} che l'estensione non sta pi@`u usando il vettore, +e che dovrebbe eliminare gli elementi marcati per l'eliminazione. +@command{gawk} libera anche ogni area di memoria che era stata allocata, +e quindi non si dovrebbe pi@`u usare il puntatore (@code{flat_array} in +questo codice) dopo aver chiamato @code{release_flattened_array()}: + +@example + if (! release_flattened_array(valore2.array_cookie, flat_array)) @{ + printf("dump_array_and_delete: non riesco a liberare \ +il vettore appiattito\n"); + goto out; + @} +@end example + +Infine, poich@'e tutto @`e andato bene, la funzione imposta il codice di ritorno +a "successo", e lo restituisce quando esce: + +@example + make_number(1.0, risultato); +out: + return risultato; +@} +@end example + +Ecco l'output ottenuto eseguendo questa parte del test: + +@example +pets ha 5 elementi +dump_array_and_delete: sym_lookup di pets effettuato +dump_array_and_delete: il vettore in input ha 5 elementi + pets["1"] = "blacky" + pets["2"] = "rusty" + pets["3"] = "sophie" +dump_array_and_delete: ho marcato l'elemento "3" per eliminazione + pets["4"] = "raincloud" + pets["5"] = "lucky" +dump_array_and_delete(pets) ha restituito 1 +dump_array_and_delete() ha rimosso l'indice "3"! +@end example + +@node Creazione di vettori +@subsubsection Come creare e popolare vettori + +Oltre a lavorare con vettori creati da codice @command{awk}, si possono +creare vettori a cui aggiungere elementi secondo le esigenze, che poi +il codice @command{awk} pu@`o utilizzare e manipolare. + +Ci sono due punti importanti da tener presente quando di creano vettori dal +codice di un'estensione: + +@itemize @value{BULLET} +@item +Il vettore appena creato deve essere subito messo nella Tabella dei simboli di +@command{gawk}. Solo dopo aver fatto questo @`e possibile aggiungere elementi +al vettore. + +@ignore +Strictly speaking, this is required only +for arrays that will have subarrays as elements; however it is +a good idea to always do this. This restriction may be relaxed +in a subsequent revision of the API. +@end ignore + +Analogamente, se si installa un nuovo vettore come sottovettore di +un vettore gi@`a esistente, +occorre prima aggiungere il nuovo vettore al suo "genitore" per poter poi +aggiungere degli elementi allo stesso. + +Quindi, il modo giusto per costruire un vettore @`e di lavorare ``dall'alto +verso il basso''. Creare il vettore, e subito aggiungerlo alla Tabella dei +simboli di @command{gawk} usando @code{sym_update()}, o installarlo come +elemento in un vettore gi@`a esistente usando @code{set_array_element()}. +Un esempio di codice @`e fornito pi@`u sotto. + +@item +Per come funziona internamente @command{gawk}, dopo aver usato +@code{sym_update()} per definire un vettore +in @command{gawk}, si deve innanzitutto ricuperare il @dfn{cookie} +del vettore dal valore passato a @command{sym_update()}, in questo modo: + +@example +awk_value_t val; +awk_array_t new_array; + +new_array = create_array(); +val.val_type = AWK_ARRAY; +val.array_cookie = new_array; + +/* aggiunge il vettore alla Tabella dei simboli */ +sym_update("array", & val); + +new_array = val.array_cookie; /* QUESTO @`E OBBLIGATORIO */ +@end example + +Se si sta installando un vettore come sottovettore, occorre anche +ricuperare il @dfn{cookie} del vettore dopo aver chiamato @code{set_element()}. +@end itemize + +Il seguente codice C @`e una semplice estensione di test per creare un vettore +con due elementi normali e con un sottovettore. Le direttive iniziali +@code{#include} e le solite dichiarazione di variabili sono state omesse per +amor di brevit@`a +(@pxref{Codice predefinito di un'estensione API}). +Il primo passo @`e creare un nuovo vettore e poi aggiungerlo alla +Tabella dei simboli: + +@example +@ignore +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#include "gawkapi.h" + +static const gawk_api_t *api; /* per far funzionare le macro di utilit@`a */ +static awk_ext_id_t *ext_id; +static const char *ext_version = "testarray extension: version 1.0"; + +int plugin_is_GPL_compatible; + +@end ignore +/* create_new_array --- creare un vettore denominato */ + +static void +create_new_array() +@{ + awk_array_t a_cookie; + awk_array_t sottovettore; + awk_value_t index, valore; + + a_cookie = create_array(); + valore.val_type = AWK_array; + valore.array_cookie = a_cookie; + + if (! sym_update("new_array", & value)) + printf("create_new_array: sym_update(\"nuovo_vettore\") \ +non riuscito!\n"); + a_cookie = valore.array_cookie; +@end example + +@noindent +Si noti come @code{a_cookie} @`e reimpostato dal campo @code{array_cookie} +nella struttura @code{valore}. + +Il secondo passo aggiunge due elementi normali a @code{nuovo_vettore}: + +@example + (void) make_const_string("salve", 5, & index); + (void) make_const_string("mondo", 5, & value); + if (! set_array_element(a_cookie, & index, & value)) @{ + printf("fill_in_array: set_array_element non riuscito\n"); + return; + @} + + (void) make_const_string("risposta", 8, & index); + (void) make_number(42.0, & value); + if (! set_array_element(a_cookie, & index, & value)) @{ + printf("fill_in_array: set_array_element non riuscito\n"); + return; + @} +@end example + +Il terzo passo @`e creare il sottovettore e aggiungerlo al vettore: + +@example + (void) make_const_string("sottovettore", 12, & index); + sottovettore = create_array(); + valore.val_type = AWK_array; + valore.array_cookie = subarray; + if (! set_array_element(a_cookie, & index, & value)) @{ + printf("fill_in_array: set_array_element non riuscito\n"); + return; + @} + sottovettore = valore.array_cookie; +@end example + +Il passo finale @`e di aggiungere al sottovettore un suo proprio elemento: + +@example + (void) make_const_string("pippo", 5, & index); + (void) make_const_string("pluto", 5, & value); + if (! set_array_element(sottovettore, & index, & value)) @{ + printf("fill_in_array: set_array_element non riuscito\n"); + return; + @} +@} +@ignore +static awk_ext_func_t func_table[] = @{ + @{ NULL, NULL, 0 @} +@}; + +/* init_testarray --- funzione ulteriore di inizializzazione */ + +static awk_bool_t init_testarray(void) +@{ + create_new_array(); + + return awk_true; +@} + +static awk_bool_t (*init_func)(void) = init_testarray; + +dl_load_func(func_table, testarray, "") +@end ignore +@end example + +Ecco uno script di esempio che carica l'estensione +e quindi stampa il valore di tutti gli elementi del vettore, +invocando nuovamente se stessa nel caso che un particolare +elemento sia a sua volta un vettore: + +@example +@@load "subarray" + +function dumparray(name, vettore, i) +@{ + for (i in vettore) + if (isarray(vettore[i])) + dumparray(name "[\"" i "\"]", vettore[i]) + else + printf("%s[\"%s\"] = %s\n", name, i, vettore[i]) +@} + +BEGIN @{ + dumparray("new_array", new_array); +@} +@end example + +Ecco il risultato dell'esecuzione dello script: + +@example +$ @kbd{AWKLIBPATH=$PWD ./gawk -f subarray.awk} +@print{} new_array["sottovettore"]["pippo"] = pluto +@print{} new_array["salve"] = mondo +@print{} new_array["risposta"] = 42 +@end example + +@noindent +(@xref{Trovare le estensioni} per ulteriori dettagli sulla +variabile d'ambiente @env{AWKLIBPATH}.) + +@node Ridirezione API +@subsection Accedere alle ridirezioni e modificarle + +La seguente funzione consente alle estensioni di accedere e di manipolare +delle ridirezioni. + +@table @code +@item awk_bool_t get_file(const char *name, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ size_t name_len, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const char *tipofile, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ int fd, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const awk_input_buf_t **ibufp, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const awk_output_buf_t **obufp); +Ricerca il file @code{name} nella tabella interna di ridirezione di +@command{gawk}. +Se @code{name} @`e @code{NULL} o @code{name_len} @`e zero, restituisce +i dati del file in input correntemente aperto il cui nome @`e memorizzato in +@code{FILENAME}. +(Questa chiamata non usa l'argomento @code{filetype}, che, quindi, pu@`o essere +lasciato indefinito). +Se il file non @`e gi@`a aperto, tenta di aprirlo. +L'argomento @code{filetype} deve terminare con uno zero binario, e dovrebbe +dovrebbe avere uno di questi valori: + +@table @code +@item ">" +Un file aperto in output. + +@item ">>" +Un file aperto in output, record aggiunti a fine file, +dopo quelli gi@`a esistenti [@dfn{append}]. + +@item "<" +Un file aperto in input. + +@item "|>" +Una @dfn{pipe} aperta in output. + +@item "|<" +Una @dfn{pipe} aperta in input. + +@item "|&" +Un coprocesso bidirezionale. +@end table + +In caso di errore, restituisce il valore @code{@dfn{awk_false}}. +Altrimenti, restituisce +@code{@dfn{awk_true}}, insieme a ulteriori informazioni sulla ridirezione +nei puntatori @code{ibufp} e @code{obufp}. +Per ridirezioni di input il valore @code{*ibufp} non dovrebbe essere +@code{NULL}, mentre @code{*obufp} dovrebbe essere @code{NULL}. +Per ridirezioni di output, +il valore di @code{*obufp} non dovrebbe essere @code{NULL}, e @code{*ibufp} +dovrebbe essere @code{NULL}. Per coprocessi bidirezionali, nessuno dei due +valori dovrebbe essere @code{NULL}. + +Normalmente, l'estensione @`e interessata a @code{(*ibufp)->fd} +e/o @code{fileno((*obufp)->fp)}. Se il file non @`e gi@`a +aperto, e l'argomento @code{fd} non @`e negativo, @command{gawk} +user@`a quel descrittore di file invece di aprire il file nella +maniera solita. Se l'@code{fd} non @`e negativo, ma il file esiste gi@`a, +@command{gawk} ignora l'@code{fd} e restituisce il file esistente. @`E +responsabilit@`a del chiamante notare che n@'e l'@code{fd} nella struttura +restituita @code{awk_input_buf_t}, n@'e l'@code{fd} nella struttura restituita +@code{awk_output_buf_t} contiene il valore richiesto. + +Si noti che fornire un descrittore di file @emph{non} @`e al momento supportato +per le @dfn{pipe}. Tuttavia, l'utilizzo di un descrittore di file +dovrebbe essere possibile per @dfn{socket} in input, output, +aggiunta-a-fine-file (append), e bidirezionale (coprocessi). +Se @code{filetype} @`e bidirezionale, @command{gawk} presuppone che sia un +@dfn{socket}! Si noti che nel caso +bidirezionale i descrittori di file in input e output possono essere +differenti. +Per essere sicuri che tutto sia andato bene, si deve controllare che uno dei due +corrisponda alla richiesta. +@end table + +Si prevede che questa funzione API verr@`a usata per parallelizzare l'I/O +e rendere disponibile una libreria per i @dfn{socket}. + +@node Variabili dell'estensione API +@subsection Variabili fornite dall'API + +L'API fornisce due insiemi di variabili. Il primo insieme contiene +informazioni sulla versione dell'API (sia la versione dell'estensione +compilata, che quella di @command{gawk}). Il secondo +insieme contiene informazioni su come @command{gawk} @`e stato invocato. + +@menu +* Versione dell'estensione:: Informazioni sulla versione API. +* Variabili informative di estens. API:: Variabili che forniscono informationi + sull'invocazione di @command{gawk}. +@end menu + +@node Versione dell'estensione +@subsubsection Costanti e variabili della versione dell'API +@cindex API, versione +@cindex versione dell'estensione API @command{gawk} +@cindex estensione @command{gawk}, versione API + +L'API fornisce sia un numero di versione ``principale'' che uno ``secondario''. +Le versioni dell'API sono disponibili al momento della compilazione, come +definizioni per il preprocessore C, a supporto della compilazione +condizionale, e come elencazione di costanti per facilitare il debug: + +@float Tabella,gawk-api-version +@caption{Costanti delle versioni API gawk} +@multitable {@b{API Version}} {@code{gawk_api_major_version}} {@code{GAWK_API_MAJOR_VERSION}} +@headitem versione API @tab Definiz. Preprocessore C @tab Costante di elenco +@item Major @tab @code{gawk_api_major_version} @tab @code{GAWK_API_MAJOR_VERSION} +@item Minor @tab @code{gawk_api_minor_version} @tab @code{GAWK_API_MINOR_VERSION} +@end multitable +@end float + +La versione secondaria aumenta quando nuove funzioni sono aggiunte all'API. +Tali nuove funzioni sono sempre aggiunte alla fine della @code{struct} dell'API. + +La versione principale aumenta (e la versione secondaria torna a zero) se +qualche tipo di dati cambia dimensione o si modifica l'ordine dei campi, o se +qualcuna delle funzioni esistenti cambia il livello di versione. + +Pu@`o capitare che un'estensione sia stata compilata con una versione +dell'API ma caricata da una versione di @command{gawk} che ne usa una +differente. Per questo motivo, la versione principale e quella secondaria +dell'API della versione in uso di @command{gawk} sono incluse nella +@code{struct} dell'API come costanti intere in sola lettura: + +@table @code +@item api->major_version +La versione principale di @command{gawk} in esecuzione. + +@item api->minor_version +La versione secondaria di @command{gawk} in esecuzione. +@end table + +Dipende dall'estensione decidere se ci sono incompatibilit@`a con l'API. +Tipicamente, basta un controllo di questo tipo: + +@example +if (api->major_version != GAWK_API_MAJOR_VERSION + || api->minor_version < GAWK_API_MINOR_VERSION) @{ + fprintf(stderr, "estensione_pippo: discordanza di versione \ +con gawk!\n"); + fprintf(stderr, "\tLa mia versione (%d, %d), versione gawk \ +(%d, %d)\n", + GAWK_API_MAJOR_VERSION, GAWK_API_MINOR_VERSION, + api->major_version, api->minor_version); + exit(1); +@} +@end example + +Questo codice @`e incluso nella macro generica @code{dl_load_func()} +presente in @file{gawkapi.h} (trattata +@iftex +nella +@end iftex +@ifnottex +in +@end ifnottex +@ref{Codice predefinito di un'estensione API}). + +@node Variabili informative di estens. API +@subsubsection Variabili informative +@cindex API, variabili informative dell'estensione +@cindex variabili informative dell'API +@cindex estensione API, variabili informative + +L'API fornisce accesso a parecchie variabili che descrivono +se le opzioni della riga di comando corrispondenti sono state specificate +quando @command{gawk} @`e stato chiamato. Le variabili sono: + +@table @code +@item do_debug +Questa variabile @`e @dfn{true} se @command{gawk} @`e stato invocato con l'opzione @option{--debug}. + +@item do_lint +Questa variabile @`e @dfn{true} se @command{gawk} @`e stato invocato con l'opzione @option{--lint}. + +@item do_mpfr +Questa variabile @`e @dfn{true} se @command{gawk} @`e stato invocato con l'opzione @option{--bignum}. + +@item do_profile +Questa variabile @`e @dfn{true} se @command{gawk} @`e stato invocato con l'opzione @option{--profile}. + +@item do_sandbox +Questa variabile @`e @dfn{true} se @command{gawk} @`e stato invocato con l'opzione @option{--sandbox}. + +@item do_traditional +Questa variabile @`e @dfn{true} se @command{gawk} @`e stato invocato con l'opzione @option{--traditional}. +@end table + +Il valore di @code{do_lint} pu@`o cambiare se il codice @command{awk} +modifica la variabile predefinita @code{LINT} (@pxref{Variabili predefinite}). +Gli altri valori non dovrebbero cambiare durante l'esecuzione. + +@node Codice predefinito di un'estensione API +@subsection Codice predefinito di interfaccia API + +Come gi@`a detto (@pxref{Panoramica sul meccanismo delle estensioni}), +le definizioni di funzioni qui presentate sono in realt@`a delle macro. +Per usare queste macro, l'estensione deve fornire una piccola quantit@`a di +codice predefinito (variabili e +funzioni) nella parte iniziale del file sorgente, usando dei nomi +standard, come descritto qui sotto. Il codice predefinito in questione @`e +anche descritto nel file di intestazione @file{gawkapi.h}: + +@example +/* Codice predefinito: */ +int plugin_is_GPL_compatible; + +static gawk_api_t *const api; +static awk_ext_id_t ext_id; +static const char *ext_version = NULL; /* o @dots{} = "qualche stringa" */ + +static awk_ext_func_t func_table[] = @{ + @{ "name", do_name, 1, 0, awk_false, NULL @}, + /* @dots{} */ +@}; + +/* O: */ + +static awk_bool_t (*init_func)(void) = NULL; + +/* OPPURE: */ + +static awk_bool_t +init_mia_estensione(void) +@{ + @dots{} +@} + +static awk_bool_t (*init_func)(void) = init_mia_estensione; + +dl_load_func(func_table, qualche_nome, "name_space_in_quotes") +@end example + +Queste variabili e funzioni sono: + +@table @code +@item int plugin_is_GPL_compatible; +Qui si dichiara che l'estensione @`e compatibile con +@ifclear FOR_PRINT +la licenza GNU GPL (@pxref{Copia}). + +@end ifclear +@ifset FOR_PRINT +la licenza GNU GPL. +@end ifset +Se l'estensione non ha questa variabile, non verr@`a caricata da @command{gawk} +(@pxref{Licenza delle estensioni}). + +@item static gawk_api_t *const api; +Questa variabile globale @code{static} dovrebbe essere impostata per +puntare al puntatore +@code{gawk_api_t} che @command{gawk} passa alla funzione (dell'estensione) +@code{dl_load()}. Questa variabile @`e usata da tutte le macro. + +@item static awk_ext_id_t ext_id; +Questa variabile globale @code{static} dovrebbe essere impostata al valore +@code{awk_ext_id_t} che @command{gawk} passa alla funzione @code{dl_load()}. +Questa variabile @`e usata da tutte le macro. + +@item static const char *ext_version = NULL; /* o @dots{} = "qualche stringa" */ +Questa variabile globale @code{static} dovrebbe essere impostata +a @code{NULL} oppure puntare a una stringa che contiene il nome e la +versione dell'estensione. + +@item static awk_ext_func_t func_table[] = @{ @dots{} @}; +Questo @`e un vettore di una o pi@`u strutture @code{awk_ext_func_t}, +come descritto in precedenza (@pxref{Funzioni di estensione}). +Pu@`o essere usato in seguito per pi@`u chiamate a +@code{add_ext_func()}. + +@c Use @var{OR} for docbook +@item static awk_bool_t (*init_func)(void) = NULL; +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @var{OR} +@itemx static awk_bool_t init_mia_estensione(void) @{ @dots{} @} +@itemx static awk_bool_t (*init_func)(void) = init_mia_estensione; +Se qualche lavoro di inizializzazione @`e necessario, si dovrebbe definire una +funzione all'uopo (crea variabili, apre file, etc.) +e poi definire il puntatore @code{init_func} che punti alla funzione +stessa. +La funzione dovrebbe restituire @code{awk_@dfn{false}} se non va a buon fine +o @code{awktrue} se tutto va bene. + +Se un'inizializzazione non @`e necessaria, si definisca il puntatore e +lo si inizializzi a @code{NULL}. + +@item dl_load_func(func_table, qualche_nome, "nome_spazio_tra_doppi_apici") +Questa macro genera una funzione @code{dl_load()} che far@`a +tutte le inizializzazioni necessarie. +@end table + +Lo scopo di tutte le variabili e dei vettori @`e di far s@`{@dotless{i}} che la +funzione @code{dl_load()} (richiamata dalla macro @code{dl_load_func()}) +faccia tutto il lavoro standard necessario, qui descritto: + +@enumerate 1 +@item +Controlla le versioni dell'API. Se la versione principale dell'estensione +non corrisponde a quella di @command{gawk} o se la versione secondaria +dell'estensione @`e maggiore di quella di @command{gawk}, stampa un messaggio +di errore fatale ed esce. + +@item +Carica le funzioni definite in @code{func_table}. +Se qualche caricamento non riesce, stampa un messaggio di +avvertimento ma continua l'esecuzione. + +@item +Se il puntatore @code{init_func} non @`e @code{NULL}, chiama la +funzione da esso puntata. Se questa restituisce @code{awk_false}, stampa un +messaggio di avvertimento. + +@item +Se @code{ext_version} non @`e @code{NULL}, registra la +stringa di versione con @command{gawk}. +@end enumerate + +@node Modifiche dalla versione API 1 +@subsection Modifiche dalla versione 1 dell'API + +La versione API corrente @emph{non} @`e compatibile a livello binario con la +versione 1 dell'API. +Le funzioni di estensione vanno ricompilate per poterle usare con la versione +corrente di @command{gawk}. + +Fortunatamente, fatti salvi alcuni possibili avvertimenti a livello di +compilazione, l'API rimane compatibile a livello di codice sorgente con la +precedente versione API. Le differenze pi@`u rilevanti sono gli ulteriori +campi nella struttura @code{awk_ext_func_t}, e l'aggiunta del terzo argomento +nella funzione di implementazione in linguaggio C. + +@node Trovare le estensioni +@section Come @command{gawk} trova le estensioni compilate +@cindex estensioni, percorso di ricerca per +@cindex estensioni, come trovarle +@cindex trovare le estensioni +@cindex percorso di ricerca per estensioni + +Le estensioni compilate vanno installate in una directory dove +@command{gawk} possa trovarle. Se @command{gawk} @`e configurato e +installato nella maniera di default, la directory dove trovare le +estensioni @`e @file{/usr/local/lib/gawk}. Si pu@`o anche specificare un +percorso di ricerca contenente una lista di directory da esaminare per la +ricerca di estensioni compilate. +@xref{AWKLIBPATH (Variabile)} per ulteriori dettagli. + +@node Esempio di estensione +@section Esempio: alcune funzioni per i file +@cindex estensione, esempio +@cindex esempio di estensione + +@quotation +@i{In qualunque posto vai, l@`a tu sei.} +@author Buckaroo Banzai +@end quotation + +@c It's enough to show chdir and stat, no need for fts + +Due utili funzioni che non sono in @command{awk} sono @code{chdir()} (per +permettere a un programma @command{awk} di cambiare directory di lavoro) e +@code{stat()} +(per far s@`{@dotless{i}} che un programma @command{awk} possa raccogliere informazioni +su un dato file). +Per illustrare l'azione dell'API, questa @value{SECTION} fornisce +queste funzioni a @command{gawk} in un'estensione. + +@menu +* Descrizione interna file:: Quello che le nuove funzioni faranno +* Operazioni interne file:: Codice per gestire file all'interno +* Usare operazioni interne file:: Come usare un'estensione esterna +@end menu + +@node Descrizione interna file +@subsection Usare @code{chdir()} e @code{stat()} + +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} mostra come usare le nuove funzioni a +livello di @command{awk} una volta che siano state integrate nell'interprete +del programma @command{gawk} in esecuzione. Usare @code{chdir()} @`e molto +semplice. Richiede un solo argomento, la nuova directory su cui +posizionarsi: + +@example +@@load "filefuncs" +@dots{} +newdir = "/home/arnold/funstuff" +ret = chdir(newdir) +if (ret < 0) @{ + printf("non riesco a passare a %s: %s\n", newdir, ERRNO) > "/dev/stderr" + exit 1 +@} +@dots{} +@end example + +Il valore restituito @`e negativo se la chiamata a @code{chdir()} non @`e riuscita, +ed @code{ERRNO} (@pxref{Variabili predefinite}) @`e impostato a una stringa +che descrive l'errore. + +Usare @code{stat()} @`e un po' pi@`u complicato. La funzione scritta in C +@code{stat()} riempie una struttura che ha una certa quantit@`a di informazioni. +La maniera corretta per immagazzinarle in @command{awk} @`e quella di riempire +un vettore associativo con le informazioni appropriate: + +@c broke printf for page breaking +@example +file = "/home/arnold/.profile" +ret = stat(file, fdata) +if (ret < 0) @{ + printf("non @`e stato possibile eseguire @command{stat} per %s: %s\n", + file, ERRNO) > "/dev/stderr" + exit 1 +@} +printf("dimensione di %s @`e %d byte\n", file, fdata["size"]) +@end example + +La funzione @code{stat()} svuota sempre il vettore che contiene i dati, +anche nel caso che la chiamata a @code{stat()} non riesca. I seguenti +elementi vengono restituiti dalla funzione: + +@table @code +@item "name" +Il nome del file oggetto della chiamata a @code{stat()}. + +@item "dev" +@itemx "ino" +I numeri di @dfn{device} e di @dfn{inode}, rispettivamente. + +@item "mode" +Il modo del file, in formato numerico. Questo include sia il tipo di file che +i suoi permessi di accesso. + +@item "nlink" +Il numero di collegamenti fisici del file (stesso file con diversi nomi). + +@item "uid" +@itemx "gid" +Gli identificativi di utente e di gruppo del possessore del file. + +@item "size" +La dimensione in byte del file. + +@item "blocks" +Il numero di blocchi su disco realmente occupati dal file. Questo pu@`o non +essere +proporzionale alla dimensione del file se il file ha delle lacune +[ossia se solo alcune parti del file esistono veramente, il resto +non @`e ancora stato riempito]. + +@item "atime" +@itemx "mtime" +@itemx "ctime" +La data e ora dell'ultimo accesso, modifica, e aggiornamento dell'@dfn{inode}, +rispettivamente. Questi sono delle marcature temporali numeriche +(misurate in secondi dal +01 gennaio 1970), che possono essere formattate dalla funzione +@code{strftime()} +(@pxref{Funzioni di tempo}). + +@item "pmode" +La modalit@`a stampabile (``printable mode'') del file. +Questo @`e una stringa che rappresenta +il tipo del file e i permessi di accesso, come sono visualizzati da +@samp{ls -l}---per esempio, @code{"drwxr-xr-x"}. + +@item "type" +Una stringa stampabile che descrive il tipo di file. Il valore @`e uno dei +seguenti: + +@table @code +@item "blockdev" +@itemx "chardev" +Il file @`e un dispositico a blocchi o a caratteri (``file speciale''). + +@ignore +@item "door" +The file is a Solaris ``door'' (special file used for +interprocess communications). +@end ignore + +@item "directory" +Il file @`e una directory. + +@item "fifo" +Il file @`e una @dfn{pipe} denominata (nota anche come FIFO [First In First +Out]). + +@item "file" +Il file @`e un file normale. + +@item "@dfn{socket}" +Il file @`e un @dfn{socket} @code{AF_UNIX} (``Unix domain'') nel +filesystem. + +@item "symlink" +Il file @`e un collegamento simbolico. +@end table + +@c 5/2013: Thanks to Corinna Vinschen for this information. +@item "devbsize" +La dimensione di un blocco per l'elemento indicizzato da @code{"blocks"}. +Questa informazione @`e derivata dalla costante @code{DEV_BSIZE} +definita in @code{<sys/param.h>} nella maggior parte dei sistemi, +o dalla costante @code{S_BLKSIZE} in @code{<sys/stat.h>} nei sistemi BSD. +Per alcuni altri sistemi il valore si basa su una conoscenza @dfn{a priori} +delle caratteristiche di un particolare sistema. +Se non si riesce a determinare il valore, viene +restituito quello di default, che @`e 512. +@end table + +Possono essere presenti diversi altri elementi, a seconda del +sistema operativo e del tipo di file. +Si pu@`o controllarne la presenza dal programma @command{awk} per mezzo +dell'operatore @code{in} +(@pxref{Visitare elementi}): + +@table @code +@item "blksize" +La dimensione preferita di un blocco per effettuare operazioni di I/O sul file. +Questo campo non @`e presente nella struttura C @code{stat} di tutti i sistemi +che rispettano lo standard POSIX. + +@item "linkval" +Se il file @`e un collegamento simbolico, questo elemento @`e il nome del +file puntato dal collegamento simbolico (cio@`e, il valore del collegamento). + +@item "rdev" +@itemx "major" +@itemx "minor" +Se il file @`e un dispositivo a blocchi o a caratteri, questi valori +rappresentano il numero del dispositivo e, rispettivamente, le componenti +principale e secondaria di quel numero. +@end table + +@node Operazioni interne file +@subsection Codice C per eseguire @code{chdir()} e @code{stat()} + +Questo @`e il codice C per queste estensioni.@footnote{La versione qui +presentata @`e +lievemente modificata per amor di semplicit@`a. Si veda @file{extension/filefuncs.c} +nella distribuzione @command{gawk} per la versione completa.} + +Il file include alcuni file di intestazione standard, e poi il file di +intestazione @file{gawkapi.h}, che fornisce le definizioni dell'API. +A queste seguono le dichiarazioni di variabili, necessarie +per usare le macro dell'API e il codice predefinito +(@pxref{Codice predefinito di un'estensione API}): + +@example +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#include "gawkapi.h" + +#include "gettext.h" +#define _(msgid) gettext(msgid) +#define N_(msgid) msgid + +#include "gawkfts.h" +#include "stack.h" + +static const gawk_api_t *api; /* per consentire il funzionamento + delle macro di utilit@`a */ +static awk_ext_id_t *ext_id; +static awk_bool_t init_filefuncs(void); +static awk_bool_t (*init_func)(void) = init_filefuncs; +static const char *ext_version = "filefuncs extension: version 1.0"; + +int plugin_is_GPL_compatible; +@end example + +@cindex programmazione, convenzioni di, estensioni @command{gawk} +@cindex estensioni @command{gawk}, convenzioni di programmazione +Per convenzione, per una funzione @command{awk} di nome @code{pippo()}, +la funzione C che la implementa @`e chiamata @code{do_pippo()}. La funzione +dovrebbe avere due argomenti. Il primo @`e un numero @code{int}, chiamato +@code{nargs}, che rappresenta il numero di argomenti passato alla funzione. +Il secondo @`e un puntatore a una struttura @code{awk_value_t}, normalmente +chiamata @code{risultato}: + +@example +/* do_chdir --- fornisce funzione chdir() + caricata dinamicamente per gawk */ + +static awk_value_t * +do_chdir(int nargs, awk_value_t *risultato, struct awk_ext_func *non_usata) +@{ + awk_value_t newdir; + int ret = -1; + + assert(risultato != NULL); +@end example + +La variabile @code{newdir} +rappresenta la nuova directory nella quale cambiare, che @`e ottenuta +tramite la funzione @code{get_argument()}. Si noti che il primo argomento @`e +quello numero zero. + +Se l'argomento @`e stato trovato con successo, la funzione invoca la chiamata di +sistema @code{chdir()}. In caso contrario, se la @code{chdir()} non riesce, +viene aggiornata la variabile @code{ERRNO}: + +@example + if (get_argument(0, AWK_STRING, & newdir)) @{ + ret = chdir(newdir.str_value.str); + if (ret < 0) + update_ERRNO_int(errno); + @} +@end example + +Infine, la funzione restituisce il codice di ritorno da @code{chdir} a +livello di @command{awk}: + +@example + return make_number(ret, risultato); +@} +@end example + +L'estensione @code{stat()} @`e pi@`u impegnativa. Dapprima abbiamo +una funzione che trasforma la stringa di autorizzazione numerica +(@dfn{mode}) in una rappresentazione stampabile +(p.es., il codice ottale @code{0644} diviene @samp{-rw-r--r--}). Questa +parte @`e qui omessa per brevit@`a. + +@example +/* format_mode --- trasforma il campo @dfn{mode} di @dfn{stat} + in qualcosa di leggibile */ + +static char * +format_mode(unsigned long fmode) +@{ + @dots{} +@} +@end example + +Viene poi una funzione per leggere dei collegamenti simbolici, anche questa +omessa per brevit@`a: + +@example +/* read_symlink --- legge un collegamento simbolico in un buffer + allocato. + @dots{} */ + +static char * +read_symlink(const char *fname, size_t bufsize, ssize_t *linksize) +@{ + @dots{} +@} +@end example + +Due funzioni ausiliarie semplificano l'immissione di valori nel +vettore che conterr@`a il risultato della chiamata a @code{stat()}: + +@example +/* array_set --- imposta un elemento di un vettore */ + +static void +array_set(awk_array_t vettore, const char *sub, awk_value_t *valore) +@{ + awk_value_t index; + + set_array_element(vettore, + make_const_string(sub, strlen(sub), & index), + valore); + +@} + +/* array_set_numeric --- imposta un elemento di un vettore con un + numero */ + +static void +array_set_numeric(awk_array_t vettore, const char *sub, double num) +@{ + awk_value_t tmp; + + array_set(vettore, sub, make_number(num, & tmp)); +@} +@end example + +La seguente funzione fa il grosso del lavoro per riempire il vettore dei +risultati @code{awk_array_t} con valori ottenuti +da una @code{struct stat} valida. Questo lavoro @`e fatto in una funzione +separata per supportare sia la funzione +@code{stat()} per @command{gawk}, che l'estensione @code{fts()}, +che @`e inclusa nello stesso file, ma non + @`e mostrata qui +(@pxref{Esempio di estensione funzioni file}). + +La prima parte della funzione @`e la dichiarazione delle variabili, +compresa una tabella per tradurre i tipi di file in stringhe: + +@example +/* fill_stat_array --- fa il lavoro di riempire un + vettore con informazioni da stat */ + +static int +fill_stat_array(const char *name, awk_array_t vettore, struct stat *sbuf) +@{ + char *pmode; /* @dfn{mode} stampabile */ + const char *type = "unknown"; + awk_value_t tmp; + static struct ftype_map @{ + unsigned int mask; + const char *type; + @} ftype_map[] = @{ + @{ S_IFREG, "file" @}, + @{ S_IFBLK, "blockdev" @}, + @{ S_IFCHR, "chardev" @}, + @{ S_IFDIR, "directory" @}, +#ifdef S_IFSOCK + @{ S_IFSOCK, "socket" @}, +#endif +#ifdef S_IFIFO + @{ S_IFIFO, "fifo" @}, +#endif +#ifdef S_IFLNK + @{ S_IFLNK, "symlink" @}, +#endif +#ifdef S_IFDOOR /* Stranezza Solaris */ + @{ S_IFDOOR, "door" @}, +#endif /* S_IFDOOR */ + @}; + int j, k; +@end example + +Il vettore di destinazione @`e svuotato di elementi, e poi il codice riempie +i vari elementi prendendoli dai valori presenti in @code{struct stat}: +@example + /* svuota il vettore */ + clear_array(vettore); + + /* riempie il vettore */ + array_set(vettore, "name", make_const_string(name, strlen(name), + & tmp)); + array_set_numeric(vettore, "dev", sbuf->st_dev); + array_set_numeric(vettore, "ino", sbuf->st_ino); + array_set_numeric(vettore, "mode", sbuf->st_mode); + array_set_numeric(vettore, "nlink", sbuf->st_nlink); + array_set_numeric(vettore, "uid", sbuf->st_uid); + array_set_numeric(vettore, "gid", sbuf->st_gid); + array_set_numeric(vettore, "size", sbuf->st_size); + array_set_numeric(vettore, "blocks", sbuf->st_blocks); + array_set_numeric(vettore, "atime", sbuf->st_atime); + array_set_numeric(vettore, "mtime", sbuf->st_mtime); + array_set_numeric(vettore, "ctime", sbuf->st_ctime); + + /* per dispositivi a blocchi o carattere, aggiunge rdev, + e il numero principale e secondario */ + if (S_ISBLK(sbuf->st_mode) || S_ISCHR(sbuf->st_mode)) @{ + array_set_numeric(vettore, "rdev", sbuf->st_rdev); + array_set_numeric(vettore, "major", major(sbuf->st_rdev)); + array_set_numeric(vettore, "minor", minor(sbuf->st_rdev)); + @} +@end example + +@noindent +L'ultima parte della funzione fa alcune aggiunte selettive +al vettore di destinazione, a seconda che siano disponibili o no +certi campi e/o il tipo del file. Viene poi restituito zero, per indicare che +tutto @`e andato bene: + +@example +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE + array_set_numeric(vettore, "blksize", sbuf->st_blksize); +#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ + + pmode = format_mode(sbuf->st_mode); + array_set(vettore, "pmode", make_const_string(pmode, strlen(pmode), + & tmp)); + + /* per collegamenti simbolici, si aggiunge un campo linkval */ + if (S_ISLNK(sbuf->st_mode)) @{ + char *buf; + ssize_t linksize; + + if ((buf = read_symlink(name, sbuf->st_size, + & linksize)) != NULL) + array_set(vettore, "linkval", + make_malloced_string(buf, linksize, & tmp)); + else + warning(ext_id, _("stat: non riesco a leggere il \ +collegamento simbolico `%s'"), + name); + @} + + /* aggiunge il tipo di campo */ + type = "unknown"; /* non dovrebbe succedere */ + for (j = 0, k = sizeof(ftype_map)/sizeof(ftype_map[0]); j < k; j++) @{ + if ((sbuf->st_mode & S_IFMT) == ftype_map[j].mask) @{ + type = ftype_map[j].type; + break; + @} + @} + + array_set(vettore, "type", make_const_string(type, strlen(type), & tmp)); + + return 0; +@} +@end example + +Del terzo argomento passato a @code{stat()} non si era ancora parlato. +Questo argomento @`e facoltativo. Se presente, dice a @code{do_stat()} di +usare la chiamata di sistema @code{stat()} invece della chiamata di sistema +@code{lstat()}. Questo avviene attraverso un puntatore a funzione: +@code{statfunc}. +@code{statfunc} @`e inizializzato per puntare a @code{lstat()} (invece che a +@code{stat()}) per ottenere le informazioni relative al file, nel caso che +il file in questione sia un +collegamento simbolico. Tuttavia, se il terzo argomento @`e specificato, +@code{statfunc} viene modificato in modo da puntare a @code{stat()}. + +Ecco la funzione @code{do_stat()}, che inizia con la dichiarazione delle +variabili e un controllo degli argomenti passati dal chiamante: + +@example +/* do_stat --- fornisce una funzione stat() per gawk */ + +static awk_value_t * +do_stat(int nargs, awk_value_t *risultato, struct awk_ext_func *non_usata) +@{ + awk_value_t file_param, array_param; + char *name; + awk_array_t vettore; + int ret; + struct stat sbuf; + /* per default si usa lstat() */ + int (*statfunc)(const char *path, struct stat *sbuf) = lstat; + + assert(risultato != NULL); +@end example + +A questo punto inizia l'elaborazione vera e propria. Per prima cosa, la +funzione esamina gli argomenti. +Poi, ottiene le informazioni relative al file. Se la funzione chiamata +(@code{lstat()} o @code{stat()}) restituisce un errore, il codice imposta +@code{ERRNO} e torna al chiamante: + +@example + /* file @`e il primo argomento, + il vettore per contenere i risultati @`e il secondo */ + if ( ! get_argument(0, AWK_STRING, & file_param) + || ! get_argument(1, AWK_ARRAY, & array_param)) @{ + warning(ext_id, _("stat: parametri errati")); + return make_number(-1, risultato); + @} + + if (nargs == 3) @{ + statfunc = stat; + @} + + name = file_param.str_value.str; + vettore = array_param.array_cookie; + + /* svuota sempre il vettore all'inizio */ + clear_array(vettore); + + /* chiama stat per il file; + in caso di errore, + imposta ERRNO e ritorna */ + ret = statfunc(name, & sbuf); + if (ret < 0) @{ + update_ERRNO_int(errno); + return make_number(ret, risultato); + @} +@end example + +Il lavoro noioso @`e svolto da @code{fill_stat_array()}, visto in +precedenza. Alla fine, la funzione restituisce il codice di ritorno +impostato da @code{fill_stat_array()}: + +@example + ret = fill_stat_array(name, vettore, & sbuf); + + return make_number(ret, risultato); +@} +@end example + +Infine, @`e necessario fornire la ``colla'' che aggrega +le nuove funzioni a @command{gawk}. + +L'estensione @code{filefuncs} comprende anche una funzione +@code{fts()}, qui omessa +(@pxref{Esempio di estensione funzioni file}). +@`E anche prevista una funzione di +inizializzazione: + +@example +/* init_filefuncs --- routine di initializazione */ + +static awk_bool_t +init_filefuncs(void) +@{ + @dots{} +@} +@end example + +Siamo quasi alla fine. Serve un vettore di strutture @code{awk_ext_func_t} +per caricare ogni funzione in @command{gawk}: + +@example +static awk_ext_func_t func_table[] = @{ + @{ "chdir", do_chdir, 1, 1, awk_false, NULL @}, + @{ "stat", do_stat, 3, 2, awk_false, NULL @}, + @dots{} +@}; +@end example + +Ogni estensione deve avere una routine di nome @code{dl_load()} per caricare +tutto ci@`o che occorre caricare. La cosa pi@`u semplice @`e di usare la macro +@code{dl_load_func()} in @code{gawkapi.h}: + +@example +/* definizione della funzione dl_load() + usando la macro standard */ + +dl_load_func(func_table, filefuncs, "") +@end example + +Abbiamo finito! + +@node Usare operazioni interne file +@subsection Integrare le estensioni + +@cindex @command{gawk}, aggiungere funzionalit@`a a +@cindex funzionalit@`a, aggiungere a @command{gawk} +@cindex aggiungere funzionalit@`a a @command{gawk} +Dopo aver scritto il codice, dev'essere possibile aggiungerlo in fase +di esecuzione all'interprete @command{gawk}. Per prima cosa, il codice +va compilato. Supponendo che le funzioni siano in +un file di nome @file{filefuncs.c}, e che @var{idir} sia la posizione +del file di intestazione @file{gawkapi.h}, +i seguenti passi@footnote{In pratica, si potrebbe decidere di usare +i comandi GNU Autotools (Automake, Autoconf, Libtool, e @command{gettext}) +per configurare e costruire le librerie necessarie. L'esposizione di come +ci@`o pu@`o essere fatto esula dal tema di questo @value{DOCUMENT}. +@xref{gawkextlib} per i puntatori a siti Internet che permettono di accedere +a questi strumenti.} creano una libreria condivisa GNU/Linux: + +@example +$ @kbd{gcc -fPIC -shared -DHAVE_CONFIG_H -c -O -g -I@var{idir} filefuncs.c} +$ @kbd{gcc -o filefuncs.so -shared filefuncs.o} +@end example + +Una volta creata la libreria, questa viene caricata usando la parola +chiave @code{@@load}: + +@example +# file testff.awk +@@load "filefuncs" + +BEGIN @{ + "pwd" | getline curdir # salva la directory corrente + close("pwd") + + chdir("/tmp") + system("pwd") # verifica l'avvenuto cambio di directory + chdir(curdir) # torna indietro + + print "Info per testff.awk" + ret = stat("testff.awk", data) + print "ret =", ret + for (i in data) + printf "data[\"%s\"] = %s\n", i, data[i] + print "testff.awk modified:", + strftime("%m %d %Y %H:%M:%S", data["mtime"]) + + print "\nInfo per JUNK" + ret = stat("JUNK", data) + print "ret =", ret + for (i in data) + printf "data[\"%s\"] = %s\n", i, data[i] + print "JUNK modified:", strftime("%m %d %Y %H:%M:%S", data["mtime"]) +@} +@end example + +La variabile d'ambiente @env{AWKLIBPATH} dice a +@command{gawk} dove @`e possibile trovare le estensioni (@pxref{Trovare le estensioni}). +La variabile viene impostata alla directory corrente, e quindi viene eseguito +il programma: + +@example +$ @kbd{AWKLIBPATH=$PWD gawk -f testff.awk} +@print{} /tmp +@print{} Info per testff.awk +@print{} ret = 0 +@print{} data["blksize"] = 4096 +@print{} data["devbsize"] = 512 +@print{} data["mtime"] = 1412004710 +@print{} data["mode"] = 33204 +@print{} data["type"] = file +@print{} data["dev"] = 2053 +@print{} data["gid"] = 1000 +@print{} data["ino"] = 10358899 +@print{} data["ctime"] = 1412004710 +@print{} data["blocks"] = 8 +@print{} data["nlink"] = 1 +@print{} data["name"] = testff.awk +@print{} data["atime"] = 1412004716 +@print{} data["pmode"] = -rw-rw-r-- +@print{} data["size"] = 666 +@print{} data["uid"] = 1000 +@print{} testff.awk modified: 09 29 2014 18:31:50 +@print{} +@print{} Info per JUNK +@print{} ret = -1 +@print{} JUNK modified: 01 01 1970 02:00:00 +@end example + +@node Esempi di estensione +@section Le estensioni di esempio incluse nella distribuzione @command{gawk} +@cindex estensioni distribuite con @command{gawk} + +Questa @value{SECTION} fornisce una breve panoramica degli esempi di +estensione inclusi nella distribuzione di @command{gawk}. Alcune di esse +sono destinate per l'uso in produzione (p.es., le estensioni +@code{filefuncs}, @code{readdir}, e +@code{inplace}). Altre sono state scritte principalmente per mostrare come +si usa l'estensione API. + +@menu +* Esempio di estensione funzioni file:: L'esempio che usa funzioni file. +* Esempio di estensione Fnmatch:: Un'interfaccia a @code{fnmatch()}. +* Esempio di estensione Fork:: Un'interfaccia a @code{fork()} e + altre funzioni di processo. +* Esempio di estensione Inplace:: Consentire modifica diretta dei file. +* Esempio di estensione Ord:: Conversioni a valore e a stringa di + caratteri. +* Esempio di estensione Readdir:: Un'interfaccia a @code{readdir()}. +* Esempio di estensione Revout:: Semplice post-processore per + invertire la stringa in output. +* Esempio di estensione Rev2way:: Processore bidirezionale per + invertire la stringa in output. +* Esempio di estensione Rwarray:: Serializzare il vettore in un + file. +* Esempio di estensione Readfile:: Leggere un intero file in una stringa. +* Esempio di estensione Time:: Un'interfaccia a @code{gettimeofday()} + e @code{sleep()}. +* Esempio di estensione API Test:: Test per la API. +@end menu + +@node Esempio di estensione funzioni file +@subsection Funzioni relative ai file + +L'estensione @code{filefuncs} include tre funzioni diverse, come descritto sotto. +L'uso @`e il seguente: + +@table @asis +@item @code{@@load "filefuncs"} +Questo @`e il modo per caricare l'estensione. + +@cindex @code{chdir()}, estensione +@cindex estensione @code{chdir()} +@item @code{risultato = chdir("/qualche/directory")} +La funzione @code{chdir()} invoca a sua volta la chiamata di sistema +@code{chdir()} per cambiare la directory corrente. Restituisce zero +se tutto va bene o un valore minore di zero in caso di errore. +In quest'ultimo caso, viene aggiornata la variabile @code{ERRNO}. + +@cindex @code{stat()}, estensione +@cindex estensione @code{stat()} +@item @code{risultato = stat("/qualche/percorso", statdata} [@code{, follow}]@code{)} +La funzione @code{stat()} invoca a sua volta la chiamata di sistema +@code{stat()}. +Restituisce zero se tutto va bene o un valore minore di zero in caso di +errore. +In quest'ultimo caso, viene aggiornata la variabile @code{ERRNO}. + +Per default, viene usata la chiamata di sistema @code{lstat()}. +Tuttavia, se alla funzione viene passato un terzo argomento, questa invoca +invece @code{stat()}. + +In tutti i casi, il vettore @code{statdata} viene preventivamente svuotato. +Quando la chiamata a @code{stat()} riesce, viene riempito il vettore +@code{statdata} con le informazioni ottenute dal fileystem, come segue: + +@multitable @columnfractions .15 .50 .20 +@headitem Indice @tab Campo in @code{struct stat} @tab Tipo file +@item @code{"name"} @tab Il @value{FN} @tab Tutti +@item @code{"dev"} @tab @code{st_dev} @tab Tutti +@item @code{"ino"} @tab @code{st_ino} @tab Tutti +@item @code{"mode"} @tab @code{st_mode} @tab Tutti +@item @code{"nlink"} @tab @code{st_nlink} @tab Tutti +@item @code{"uid"} @tab @code{st_uid} @tab Tutti +@item @code{"gid"} @tab @code{st_gid} @tab Tutti +@item @code{"size"} @tab @code{st_size} @tab Tutti +@item @code{"atime"} @tab @code{st_atime} @tab Tutti +@item @code{"mtime"} @tab @code{st_mtime} @tab Tutti +@item @code{"ctime"} @tab @code{st_ctime} @tab Tutti +@item @code{"rdev"} @tab @code{st_rdev} @tab Dispositivi +@item @code{"major"} @tab @code{st_major} @tab Dispositivi +@item @code{"minor"} @tab @code{st_minor} @tab Dispositivi +@item @code{"blksize"} @tab @code{st_blksize} @tab Tutti +@item @code{"pmode"} @tab Una versione leggibile del valore dell'autorizzazione, +come quello stampato dal comando +@command{ls} (per esempio, @code{"-rwxr-xr-x"}) @tab Tutti +@item @code{"linkval"} @tab Il valore del collegamento simbolico @tab +Collegamenti simbolici +@item @code{"type"} @tab Il tipo del file in formato stringa---pu@`o essere +@code{"file"}, +@code{"blockdev"}, +@code{"chardev"}, +@code{"directory"}, +@code{"socket"}, +@code{"fifo"}, +@code{"symlink"}, +@code{"door"} +o +@code{"unknown"} +(non tutti i sistemi supportano tutti i tipi file) @tab Tutti +@end multitable + +@cindex @code{fts()}, estensione +@cindex estensione @code{fts()} +@item @code{flags = or(FTS_PHYSICAL, ...)} +@itemx @code{risultato = fts(pathlist, flags, filedata)} +Percorre gli alberi di file elencati in @code{pathlist} e riempie il vettore +@code{filedata}, come descritto qui di seguito. @code{flags} @`e l'operazione +@dfn{OR} @dfn{bit} a @dfn{bit} di parecchi valori predefiniti, pure descritti +pi@`u sotto. +Restituisce zero in assenza di errori, in caso contrario restituisce @minus{}1. +@end table + +La funzione @code{fts()} invoca a sua volta la routine di libreria C +@code{fts()} per percorrere gerarchie di file. Invece di restituire i dati +relativi ai file uno per volta in sequenza, +riempie un vettore multidimensionale con i dati di ogni file e directory +che risiedono nelle gerarchie richieste. + +Gli argomenti sono i seguenti: + +@table @code +@item pathlist +Un vettore di @value{FNS}. Sono usati i valori dei singoli elementi; +gli indici che puntano a tali valori vengono ignorati. + +@item flags +Questo dovrebbe essere l'@dfn{OR} @dfn{bit} a @dfn{bit} di uno o pi@`u dei +seguenti valori dei flag costanti predefiniti. +Almeno uno dei due flag @code{FTS_LOGICAL} +o @code{FTS_PHYSICAL} dev'essere impostato; in caso contrario +@code{fts()} restituisce una segnalazione di errore e imposta @code{ERRNO}. +I flag sono: + +@c nested table +@table @code +@item FTS_LOGICAL +Passa in rassegna i file in modo ``logico'', e quindi l'informazione restituita +per un collegamento simbolico @`e quella relativa al file puntato, e non al +collegamento simbolico stesso. Questo flag @`e mutuamente esclusivo con +@code{FTS_PHYSICAL}. + +@item FTS_PHYSICAL +Passa in rassegna i file in modo ``fisico'', e quindi l'informazione restituita +per un collegamento simbolico @`e quella relativa al collegamento simbolico +stesso. Questo flag @`e mutuamente esclusivo con @code{FTS_LOGICAL}. + +@item FTS_NOCHDIR +Per migliorare le prestazioni, la routine di libreria C @code{fts()} +cambia directory mentre percorre una gerarchia di file. Questo flag +disabilita quell'ottimizzazione. + +@item FTS_COMFOLLOW +Si accede al file puntato da un collegamento simbolico esistente in @code{pathlist}, +anche se @code{FTS_LOGICAL} non @`e stato impostato. + +@item FTS_SEEDOT +Per default, la routine di libreria C @code{fts()} non restituisce +informazioni per i file +@file{"."} (punto) e @file{".."} (punto-punto). Quest'opzione richiede +l'informazione anche per @file{".."}. (L'estensione ritorna sempre +l'informazione per @file{"."}; maggiori dettagli pi@`u sotto.) + +@item FTS_XDEV +Mentre si percorre un filesystem, non passare mai a un filesystem montato +diverso da quello in cui si opera. +@c Pu@`o succedere nel caso di collegamenti simbolici, che contengono un nome di file +@c che si trova da tutt'altra parte +@c lrwxrwxrwx 1 root root 6 ago 6 2015 /aca -> /d/aca +@c /d/aca: +@c /dev/sda6 115234344 15648380 93709280 15% /d +@c / (e il collegamento simbolico /aca) +@c /dev/sda1 37308224 13573368 21816644 39% / +@end table + +@item filedata +Il vettore @code{filedata} contiene i risultati. +La funzione @code{fts()} lo svuota all'inizio. In seguito viene creato +un elemento in @code{filedata} per ogni elemento in @code{pathlist}. +L'indice @`e il nome della directory o del file specificato in @code{pathlist}. +L'elemento puntato da questo indice @`e a sua volta un vettore. Ci sono due +casi: + +@c nested table +@table @emph +@item Il percorso @`e un file +In questo caso, il vettore contiene due o tre elementi: + +@c doubly nested table +@table @code +@item "path" +Il percorso completo di questo file, a partire dalla directory radice (``root'') +indicata nel vettore @code{pathlist}. + +@item "stat" +Questo elemento @`e esso stesso un vettore, contenente le stesse informazioni +fornite dalla funzione @code{stat()} vista in precedenza a proposito del suo +argomento +@code{statdata}. L'elemento pu@`o non essere presente se la chiamata +di sistema @code{stat()} per il file non @`e riuscita. + +@item "error" +Se qualche tipo di errore si verifica durante l'elaborazione, il vettore +conterr@`a anche un elemento con chiave @code{"error"}, che @`e una stringa +che descrive l'errore. +@end table + +@item Il percorso @`e una directory +In questo caso, nel vettore viene creato un elemento per ogni elemento +contenuto nella directory. Se un elemento della directory @`e un +file, l'azione del programma @`e la stessa descritta sopra per un file. +Se invece la directory contiene delle sottodirectory, l'elemento creato +nel vettore @`e (ricorsivamente) a sua volta un vettore che descrive la +sottodirectory. Se fra i flag @`e stato +specificato il flag @code{FTS_SEEDOT}, +ci sar@`a anche un elemento di nome +@code{".."}. Questo elemento sar@`a un vettore contenente i dati restituiti +da un'invocazione di @code{stat()}. + +Inoltre, ci sar@`a un elemento il cui indice @`e @code{"."}. +Questo elemento @`e un vettore contenente gli stessi due o tre elementi che +sono messi a disposizione per un file: @code{"path"}, @code{"stat"}, +ed @code{"error"}. +@end table +@end table + +La funzione @code{fts()} restituisce zero in assenza di errori. +in caso contrario, restituisce @minus{}1. + +@quotation NOTA +L'estensione @code{fts()} non imita esattamente l'interfaccia fornita dalla +routine di libreria C @code{fts()}, ma sceglie di fornire un'interfaccia +basata sui vettori associativi, che @`e pi@`u adeguata per l'uso da parte di un +programma @command{awk}. Questo +implica la mancanza di una funzione di +confronto, poich@'e @command{gawk} gi@`a +prevede la possibilit@`a di mettere facilmente nell'ordine desiderato gli +elementi di un vettore. +Anche se un'interfaccia modellata su @code{fts_read()} avrebbe potuto essere +fornita, @`e sembrato pi@`u naturale mettere a disposizione un vettore +multidimensionale, che rappresenta la gerarchia dei file e le informazioni +relative a ognuno di essi. +@end quotation + +Si veda il file @file{test/fts.awk} nella distribuzione di @command{gawk} +per un esempio di uso dell'estensione @code{fts()}. + +@node Esempio di estensione Fnmatch +@subsection Un'interfaccia a @code{fnmatch()} + +Quest'estensione fornisce un'interfaccia per utilizzare la funzione di +libreria C @code{fnmatch()}. Si usa cos@`{@dotless{i}}: + +@table @code +@item @@load "fnmatch" +@`E questo il modo per caricare l'estensione. + +@cindex @code{fnmatch()}, estensione +@cindex estensione @code{fnmatch()} +@item risultato = fnmatch(pattern, stringa, flags) +Il valore restituito @`e zero se tutto va bene, oppure @code{FNM_NOMATCH} +se la funzione non ha trovato alcuna corrispondenza, o +un valore differente, diverso da zero, se si @`e verificato un errore. +@end table + +Oltre a rendere disponibile la funzione @code{fnmatch()}, l'estensione +di @code{fnmatch} definisce una costante (@code{FNM_NOMATCH}), e un vettore +con dei valori di flag, di nome @code{FNM}. + +Gli argomenti per @code{fnmatch()} sono: + +@table @code +@item pattern +L'espressione regolare con cui confrontare @value{FN} + +@item stringa +La stringa @value{FN} + +@item flags +Pu@`o valere zero o essere l'@dfn{OR} @dfn{bit} a @dfn{bit} di uno o pi@`u flag +nel vettore @code{FNM} +@end table + +I flag sono i seguenti: + +@multitable @columnfractions .40 .60 +@headitem Elemento del vettore @tab Flag corrispondente definito da @code{fnmatch()} +@item @code{FNM["CASEFOLD"]} @tab @code{FNM_CASEFOLD} +@item @code{FNM["FILE_NAME"]} @tab @code{FNM_FILE_NAME} +@item @code{FNM["LEADING_DIR"]} @tab @code{FNM_LEADING_DIR} +@item @code{FNM["NOESCAPE"]} @tab @code{FNM_NOESCAPE} +@item @code{FNM["PATHNAME"]} @tab @code{FNM_PATHNAME} +@item @code{FNM["PERIOD"]} @tab @code{FNM_PERIOD} +@end multitable + +Ecco un esempio: + +@example +@@load "fnmatch" +@dots{} +flags = or(FNM["PERIOD"], FNM["NOESCAPE"]) +if (fnmatch("*.a", "pippo.c", flags) == FNM_NOMATCH) + print "nessuna corrispondenza" +@end example + +@node Esempio di estensione Fork +@subsection Un'interfaccia a @code{fork()}, @code{wait()}, e @code{waitpid()} + +L'estensione @code{fork} mette a disposizione tre funzioni, come segue: + +@table @code +@item @@load "fork" +Questo @`e il modo per caricare l'estensione. + +@cindex @code{fork()}, estensione +@cindex estensione @code{fork()} +@item pid = fork() +Questa funzione crea un nuovo processo. Il valore restituito @`e zero nel +processo ``figlio'' e il numero che identifica il nuovo processo +(@dfn{pid}) nel processo ``padre'', o @minus{}1 +in caso di errore. In quest'ultimo caso, @code{ERRNO} indica il problema. +Nel processo figlio, gli elementi @code{PROCINFO["pid"]} e +@code{PROCINFO["ppid"]} vengono aggiornati per riflettere i valori corretti. + +@cindex @code{waitpid()}, estensione +@cindex estensione @code{waitpid()} +@item ret = waitpid(pid) +Questa funzione ha un unico argomento numerico, l'identificativo del processo +di cui aspettare l'esito. Il valore di ritorno @`e quello restituito dalla +chiamata di sistema @code{waitpid()}. + +@cindex @code{wait()}, estensione +@cindex estensione @code{wait()} +@item ret = wait() +Questa funzione attende che il primo processo ``figlio'' termini. +Il valore restituito @`e quello della chiamata di sistema @code{wait()}. +@end table + +Non c'@`e una funzione corrispondente alla chiamata di sistema @code{exec()}. + +Ecco un esempio: + +@example +@@load "fork" +@dots{} +if ((pid = fork()) == 0) + print "salve dal processo figlio" +else + print "salve dal processo padre" +@end example + +@node Esempio di estensione Inplace +@subsection Consentire la modifica in loco dei file + +@cindex @code{inplace}, estensione +@cindex estensione @code{inplace} +L'estensione @code{inplace} svolge un lavoro simile a quello +dell'opzione @option{-i} nel programma di utilit@`a GNU @command{sed}, +che svolge delle funzioni di modifica ``al volo'' su ogni file in input. +Viene usato il file @file{inplace.awk}, caricato dinamicamente, per richiamare +l'estensione in maniera corretta: + +@example +@c file eg/lib/inplace.awk +@group +# inplace --- carica e richiama l'estensione inplace. + +@@load "inplace" + +# @`E buona cosa impostare INPLACE_SUFFIX in modo da fare +# una copia di backup. +# Per esempio, si potrebbe impostare INPLACE_SUFFIX a .bak +# sulla riga di comando, o in una regola BEGIN. + +# Per default, ogni file specificato sulla riga di comando +# verr@`a modificato sovrascrivendo il file originale. +# Ma @`e possibile evitarlo specificando l'argomento inplace=0 +# davanti al nome del file che non si desidera elaborare in questo modo. +# Si pu@`o poi abilitare di nuovo l'aggiornamento diretto del file +# sulla riga di comando, specificando inplace=1 prima del file +# che si vuole modificare direttamente. + +# N.B. La funzione inplace_end() @`e invocata nelle regole +# BEGINFILE ed END, in modo che ogni eventuale azione +# in una regola ENDFILE sar@`a ridiretta come previsto. + +BEGIN @{ + inplace = 1 # abilitato per default +@} + +BEGINFILE @{ + if (_inplace_filename != "") + inplace_end(_inplace_filename, INPLACE_SUFFIX) + if (inplace) + inplace_begin(_inplace_filename = FILENAME, INPLACE_SUFFIX) + else + _inplace_filename = "" +@} + +END @{ + if (_inplace_filename != "") + inplace_end(_inplace_filename, INPLACE_SUFFIX) +@} +@end group +@c endfile +@end example + +Per ogni file elaborato, l'estensione ridirige lo +standard output verso un file temporaneo definito in modo da avere lo stesso +proprietario e le stesse autorizzazioni del file originale. Dopo che il file +@`e stato elaborato, l'estensione riporta lo standard output alla sua +destinazione originale. +Se @code{INPLACE_SUFFIX} non @`e una stringa vuota, il file originale @`e +collegato a un @value{FN} di backup, creato aggiungendo il +suffisso al nome originale. +Infine, il file temporaneo @`e rinominato in modo da essere lo stesso del +@value{FN} originario. + +Si noti che l'uso di questa funzionalit@`a pu@`o essere controllato +specificando @samp{inplace=0} sulla riga di comando, prima del nome del file +che non dovrebbe essere elaborato come appena descritto. Si pu@`o richiedere +ancora l'aggiornamento diretto di un file, specificando l'argomento +@samp{inplace=1} davanti al nome del file da elaborare in maniera diretta. + +La variabile @code{_inplace_filename} serve per tener traccia del nome del +file corrente, in modo da non eseguire la funzione @code{inplace_end()} prima +di aver elaborato il primo file. + +Se si verifica un errore, l'estensione emette un messaggio di errore fatale +per terminare l'elaborazione immediatamente, senza danneggiare il +file originale. + +Ecco alcuni semplici esempi: + +@example +$ @kbd{gawk -i inplace '@{ gsub(/pippo/, "pluto") @}; @{ print @}' file1 file2 file3} +@end example + +Per mantenere una copia di backup del file originale, si provi a fare cos@`{@dotless{i}}: + +@example +$ @kbd{gawk -i inplace -v INPLACE_SUFFIX=.bak '@{ gsub(/pippo/, "pluto") @}} +> @kbd{@{ print @}' file1 file2 file3} +@end example + +Si noti che, anche se l'estensione tenta di mantenere il proprietario e i +permessi di accesso del file originario, non viene tentata la copia degli +ulteriori permessi di accesso +(@dfn{ACL - Access Control Lists}) del file originale. + +Se il programma termina prima del previsto, come potrebbe succedere se riceve +dal sistema un segnale non gestito, pu@`o lasciare come residuo un file +temporaneo. + +@node Esempio di estensione Ord +@subsection Caratteri e valori numerici: @code{ord()} e @code{chr()} + +L'estensione @code{ordchr} aggiunge due funzioni, di nome +@code{ord()} e @code{chr()}, come segue: + +@table @code +@item @@load "ordchr" +Questo @`e il modo per caricare l'estensione. + +@cindex @code{ord()}, estensione +@cindex estensione @code{Ord} +@item numero = ord(stringa) +Restituisce il valore numerico del primo carattere in @code{stringa}. + +@cindex @code{Chr}, estensione +@cindex estensione @code{Chr} +@item char = chr(number) +Restituisce una stringa il cui primo carattere @`e quello rappresentato +da @code{number}. +@end table + +Queste funzioni sono ispirate alle funzioni del linguaggio Pascal +dallo stesso nome. Ecco un esempio: + +@example +@@load "ordchr" +@dots{} +printf("Il valore numerico di 'A' @`e %d\n", ord("A")) +printf("Il valore come stringa di 65 @`e %s\n", chr(65)) +@end example + +@node Esempio di estensione Readdir +@subsection Leggere directory + +L'estensione @code{readdir} aggiunge un analizzatore di input +per esaminare directory. +L'uso @`e il seguente: + +@cindex @code{readdir}, estensione +@cindex estensione @code{readdir} +@example +@@load "readdir" +@end example + +Quando quest'estensione @`e in uso, invece che saltare le +directory presenti sulla riga di comando, (o accedute tramite @code{getline}), +queste sono lette, e ogni elemento della directory @`e restituito come +un record. + +Il record consiste di tre campi. I primi due sono il numero di @dfn{inode} e +il @value{FN}, separati fra loro da una barra. +Nei sistemi in cui l'elemento di directory contiene il tipo del file, +il record ha un terzo campo (pure separato da una barra), composto da una +sola lettera, che indica il tipo del file. Le lettere e i tipi di file a cui +corrispondono sono mostrate in @ref{table-readdir-file-types}. + +@float Tabella,table-readdir-file-types +@caption{Tipi file restituiti dall'estensione @code{readdir}} +@multitable @columnfractions .1 .9 +@headitem Lettera @tab Tipo di file +@item @code{b} @tab Dispositivo a blocchi +@item @code{c} @tab Dispositivo a caratteri +@item @code{d} @tab Directory +@item @code{f} @tab File normale +@item @code{l} @tab Collegamento simbolico +@item @code{p} @tab @dfn{pipe} con nome (FIFO) +@item @code{s} @tab @dfn{socket} +@item @code{u} @tab Tutto il resto (sconosciuto) +@end multitable +@end float + +Nei sistemi che non contengono l'informazione sul tipo del file, il terzo +campo @`e sempre @samp{u}. + +@quotation NOTA +Nei sistemi GNU/Linux, ci sono fileystem che non supportano il campo +@code{d_type} (si veda la pagina di manuale @i{readdir}(3)), e in questo caso +il tipo di file @`e sempre @samp{u}. Si pu@`o usare l'estensione +@code{filefuncs} per chiamare @code{stat()} e ottenere l'informazione +corretta sul tipo di file. +@end quotation + +Ecco un esempio: + +@example +@@load "readdir" +@dots{} +BEGIN @{ FS = "/" @} +@{ print "@value{FN} @`e", $2 @} +@end example + +@node Esempio di estensione Revout +@subsection Invertire la stringa in output + +L'estensione @code{revoutput} aggiunge un semplice processore +di output che inverte i caratteri di ogni riga in output. Serve a dimostrare +come @`e possibile scrivere un processore di output, anche se pu@`o essere +a prima vista vagamente divertente. +Ecco un esempio: + +@cindex @code{revoutput}, estensione +@cindex estensione @code{revoutput} +@example +@@load "revoutput" + +BEGIN @{ + REVOUT = 1 + print "non v'allarmate" > "/dev/stdout" +@} +@end example + +L'output di questo programma @`e @samp{etamralla'v non}. + +@node Esempio di estensione Rev2way +@subsection Esempio di I/O bidirezionale + +L'estensione @code{revtwoway} aggiunge un semplice processore +bidirezionale che inverte i caratteri di ogni riga che riceve, per farla +poi rileggere dal programma @command{awk}. Il motivo per cui @`e stata scritta +@`e quello di mostrare come si scrive un processore bidirezionale, anche se pu@`o +sembrare un programma vagamente divertente. +Il seguente esempio mostra come usarlo: + +@cindex @code{revtwoway}, estensione +@cindex estensione @code{revtwoway} +@example +@@load "revtwoway" + +BEGIN @{ + cmd = "/specchio/magico" + print "non v'allarmate" |& cmd + cmd |& getline risultato + print risultato + close(cmd) +@} +@end example + +L'output di questo programma +@ifnotinfo +anche in questo caso @`e: +@end ifnotinfo +@ifinfo +@`e: +@end ifinfo +@samp{etamralla'v non}. + +@node Esempio di estensione Rwarray +@subsection Scaricare e ricaricare un vettore + +L'estensione @code{rwarray} aggiunge due funzioni, +di nome @code{writea()} e @code{reada()}, come segue: + +@table @code +@item @@load "rwarray" +Questo @`e il modo per caricare l'estensione. + +@cindex @code{writea()}, estensione +@cindex estensione @code{writea()} +@item ret = writea(file, vettore) +Questa funzione ha come argomento una stringa, che @`e il nome del file +sul quale scaricare il vettore, e il vettore stesso @`e il secondo argomento. +@code{writea()} @`e in grado di gestire vettori di vettori. Restituisce il +valore uno se completa il lavoro o zero se non va a buon fine. + +@cindex @code{reada()}, estensione +@cindex estensione @code{reada()} +@item ret = reada(file, vettore) +@code{reada()} @`e la funzione inversa di @code{writea()}; +legge il file il cui nome @`e fornito come primo argomento, riempiendo il +vettore il cui nome @`e il secondo argomento. Il vettore viene preventivamente +svuotato. +Anche in questo caso, il valore restituito @`e uno se tutto va bene o zero se +la funzione non va a buon fine. +@end table + +Il vettore creato da @code{reada()} @`e identico a quello scritto da +@code{writea()} nel senso che i contenuti sono gli stessi. Tuttavia, +per come @`e strutturata la funzione, l'ordine di attraversamento del vettore +ricreato @`e quasi certamente differente da quello del vettore originale. +Poich@'e l'ordine di attraversamento di un vettore @`e, per default, indefinito +in @command{awk}, questo non @`e (tecnicamente) un problema. Se serve che +l'attraversamento del vettore avvenga in un ordine preciso, si possono usare +le funzionalit@`a di ordinamento di un vettore disponibili in @command{gawk} +(@pxref{Ordinamento di vettori}). + +Il file contiene dati in formato binario. Tutti i valori interi sono scritti +in @dfn{network byte order}@footnote{Cio@`e, nella maniera con cui sarebbero +normalmente scritti in un testo, con le cifre pi@`u significative del +numero contenute nella parte sinistra, e quelle meno significative +nella parte destra della rappresentazione binaria del numero.}. +Tuttavia, i valori in virgola mobile a doppia precisione sono scritti come +dati binari nativi. Quindi, vettori che contengono solo dati in formato +stringa possono essere scaricati da un sistema con un certo ordine di byte +e ripristinati su un sistema con un ordine di byte differente, anche se +un test al riguardo non @`e mai stato fatto. + +Ecco un esempio: + +@example +@@load "rwarray" +@dots{} +ret = writea("scaricato.bin", vettore) +@dots{} +ret = reada("scaricato.bin", vettore) +@end example + +@node Esempio di estensione Readfile +@subsection Leggere un intero file in una stringa + +L'estensione @code{readfile} aggiunge una sola funzione +di nome @code{readfile()}, e un analizzatore di input: + +@table @code +@item @@load "readfile" +Questo @`e il modo per caricare l'estensione. + +@cindex @code{readfile()}, estensione +@cindex estensione @code{readfile()} +@item risultato = readfile("/qualche/persorso") +L'argomento @`e il nome del file da leggere. Il valore restituito @`e una +stringa contenente l'intero contenuto del file richiesto. In caso di errore, +la funzione restituisce la stringa vuota e imposta @code{ERRNO}. + +@item BEGIN @{ PROCINFO["readfile"] = 1 @} +Inoltre, l'estensione aggiunge un analizzatore di input che @`e attivato se +l'elemento @code{PROCINFO["readfile"]} esiste. +Quando l'analizzatore @`e attivato, ogni file in input @`e restituito interamente +come @code{$0}. +La variabile @code{RT} @`e impostata alla stringa nulla. +@end table + +Ecco un esempio: + +@example +@@load "readfile" +@dots{} +contents = readfile("/percorso/del/file"); +if (contents == "" && ERRNO != "") @{ + print("problema in lettura file", ERRNO) > "/dev/stderr" + ... +@} +@end example + +@node Esempio di estensione Time +@subsection Funzioni dell'estensione time + +L'estensione @code{time} aggiunge due funzioni, di nome +@code{gettimeofday()} e @code{sleep()}, come segue: + +@table @code +@item @@load "time" +Questo @`e il modo per caricare l'estensione. + +@cindex @code{gettimeofday()}, estensione +@cindex estensione @code{gettimeofday()} +@item ora_corrente = gettimeofday() +Restituisce il numero di secondi trascorsi dalle ore 00:00 del giorno +01/01/1970 UTC come valore a virgola mobile. +Se questa informazione non @`e disponibile nella piattaforma in uso, +restituisce @minus{}1 e imposta @code{ERRNO}. Il valore fornito dovrebbe +avere la precisione di una frazione di +secondo, ma la precisione effettiva pu@`o variare a seconda della +piattaforma. +Se la chiamata di sistema standard C @code{gettimeofday()} @`e disponibile +nella piattaforma in uso, questo @`e il valore restituito. In caso contrario, +se si sta lavorando con MS-Windows, la chiamata di sistema @`e fatta a +@code{GetSystemTimeAsFileTime()}. + +@cindex @code{sleep()}, estensione +@cindex estensione @code{sleep()} +@item risultato = sleep(@var{secondi}) +Il programma @command{gawk} resta inattivo (dorme) per i @var{secondi} +specificati. Se @var{secondi} ha un valore negativo, +o la chiamata di sistema non riesce, restituisce @minus{}1 e imposta @code{ERRNO}. +In caso contrario, restituisce zero dopo aver lasciato trascorrere +la quantit@`a di tempo indicata. +Si noti che @var{secondi} pu@`o essere un numero a virgola mobile (non solo un +numero intero). +Dettagli di implementazione: a seconda della disponibilit@`a nel sistema in uso, +questa funzione tenta di usare @code{nanosleep()} o @code{select()} per +ottenere il tempo di attesa richiesto. +@end table + +@node Esempio di estensione API Test +@subsection Test per la API +@cindex @code{testext}, estensione +@cindex estensione @code{testext} + +L'estensione @code{testext} controlla la funzionalit@`a di +parti dell'API delle estensioni che non sono utilizzate negli altri esempi. +Il file @file{extension/testext.c} +contiene sia il codice C per l'estensione che il codice @command{awk} +(tra i commenti del codice C) per eseguire i test. L'ambiente di test +estrae il codice sorgente @command{awk} ed esegue i test. Si veda il file +sorgente per maggiori informazioni. + +@node gawkextlib +@section Il progetto @code{gawkextlib} +@cindex @code{gawkextlib}, estensioni +@cindex estensioni, @code{gawkextlib} +@cindex estensioni, dove trovarle + +@cindex @code{gawkextlib}, progetto +@cindex progetto @code{gawkextlib} +Il progetto @uref{http://sourceforge.net/projects/gawkextlib/, @code{gawkextlib}} +fornisce varie estensioni per @command{gawk}, compresa una per +l'elaborazione dei file XML. Questa @`e un'evoluzione del progetto noto come +@command{xgawk} (XML @command{gawk}). + +Al momento della stesura di questo testo, ci sono otto estensioni: + +@itemize @value{BULLET} +@item +Estensione @code{errno} + +@item +Estensione GD graphics library + +@item +Estensione libreria MPFR +(fornisce l'accesso a varie funzioni MPFR non previste dal supporto nativo +di MPFR disponibile in @command{gawk}) + +@item +Estensione PDF + +@item +Estensione PostgreSQL + +@item +Estensione Redis + +@item +Estensione Select + +@item +Estensione analizzatore XML, usando la libreria di analisi XML +@uref{http://expat.sourceforge.net, Expat} +@end itemize + +@cindex @command{git}, programma di utilit@`a +@cindex programma di utilit@`a @command{git} +Si pu@`o scaricare il codice del progetto @code{gawkextlib} +usando il codice sorgente mantenuto tramite +@uref{http://git-scm.com, Git}. +Il comando per farlo @`e il seguente: + +@example +git clone git://git.code.sf.net/p/gawkextlib/code gawkextlib-code +@end example + +@cindex Expat, libreria per analizzare XML +@cindex XML, Expat, libreria per analizzare +Per poter compilare e usare l'estensione XML, @`e necessario installare +la libreria di analisi XML @uref{http://expat.sourceforge.net, Expat}. + +Inoltre, @`e necessario installare gli strumenti GNU Autotools +(@uref{http://www.gnu.org/software/autoconf, Autoconf}, +@uref{http://www.gnu.org/software/automake, Automake}, +@uref{http://www.gnu.org/software/libtool, Libtool} +e +@uref{http://www.gnu.org/software/gettext, GNU @command{gettext}}). + +La semplice procedura per compilare e testare @code{gawkextlib} @`e la seguente. +Dapprima, occorre compilare e installare @command{gawk}: + +@example +cd .../percorso/del/sorgente/gawk +./configure --prefix=/tmp/newgawk @ii{Installa in /tmp/newgawk per ora} +make && make check @ii{Compila e controlla che tutto sia a posto} +make install @ii{Installa gawk} +@end example + +Poi, dal sito @url{http://sourceforge.net/projects/gawkextlib/files} si deve +scaricare @code{gawkextlib} e le estensioni che si vogliono installare. +Il file @file{README} del sito spiega come compilare il codice. Se si @`e +installato @command{gawk} in una posizione non-standard, occorre +specificare @code{./configure --with-gawk=@var{/percorso/del/programma/gawk}} +per far s@`{@dotless{i}} che venga trovato. +Pu@`o essere necessario usare il programma di utilit@`a @command{sudo} +per installare sia @command{gawk} che @code{gawkextlib}, a seconda di come +funziona il sistema su cui si lavora. + +Chi scrive un'estensione e desidera condividerla con altri utenti +@command{gawk}, pu@`o prendere in considerazione l'idea di farlo attraverso +il progetto @code{gawkextlib}. +Si veda il sito web del progetto per maggiori informazioni. + +@node Sommario delle estensioni +@section Sommario + +@itemize @value{BULLET} +@item +Si possono scrivere estensioni (dette anche @dfn{plug-in}) +per @command{gawk} +nel linguaggio C o C++ usando l'interfaccia di programmazione applicativa +(API) definita dagli sviluppatori di +@command{gawk}. + +@item +Le estensioni devono avere una licenza compatibile con la +GNU General Public License (GPL), e devono dichiararlo definendo un'apposita +variabile di nome +@code{plugin_is_GPL_compatibile}. + +@item +La comunicazione tra @command{gawk} e un'estensione @`e bidirezionale. +@command{gawk} passa all'estensione una struttura (@code{struct}) che contiene +vari campi di dati e puntatori a funzione. L'estensione pu@`o poi chiamare +funzioni all'interno di @command{gawk} tramite dei puntatori a funzioni +per svolgere alcuni compiti. + +@item +Uno di questi compiti @`e di ``registrare'' il nome e l'implementazione di +nuove funzioni a livello di @command{awk} con @command{gawk}. +L'implementazione ha la forma di un puntatore del linguaggio C, +cui @`e associato un dato livello di versione. +Per convenzione, le funzioni di implementazione hanno nome +@code{do_@var{XXXX}()} per una funzione a livello di @command{awk} di nome +@code{@var{XXXX}()}. + +@item +L'API @`e definita in un file di intestazione di nome @file{gawkapi.h}. +Occorre includere alcuni file di intestazione standard @emph{prima} di +includere tale intestazione nel codice sorgente. + +@item +Vengono forniti dei puntatori a funzioni dell'API per i seguenti tipi di +operazioni: + +@itemize @value{BULLET} +@item +Allocare, riallocare, e liberare memoria + +@item +Registrare funzioni (si possono registrare +funzioni di estensione, +funzioni ausiliarie di pulizia (@dfn{callbacks}), +una stringa di versione, +degli analizzatori di input, +dei processori di output, +e dei processori bidirezionali) + +@item +Stampare messaggi fatali, non fatali, di avvertimento, e avvertimenti ``lint'' + +@item +Aggiornare @code{ERRNO} o annullarlo + +@item +Accedere a parametri, come pure convertire un parametro di tipo non definito +in un vettore + +@item +Accedere alla tabella dei simboli (ricuperare il valore di una +variabile globale, crearne una nuova o modificarne una esistente) + +@item +Creare e rilasciare valori nascosti; questo consente di usare in modo +efficiente lo stesso valore per pi@`u variabili e pu@`o migliorare di molto le +prestazioni del programma + +@item +Manipolare vettori +(ricuperare, aggiungere, cancellare e modificare elementi; +ottenere il numero di elementi in un vettore; +creare un nuovo vettore; +svuotare un vettore; +e +appiattire un vettore per poterlo percorrere facilmente con un ciclo in +stile C, visitando tutti i suoi indici ed elementi) +@end itemize + +@item +L'API definisce diversi tipi di dati standard per rappresentare +valori di variabili, elementi di vettore e vettori presenti in @command{awk}. + +@item +L'API fornisce funzioni di servizio per definire dei valori. +Sono anche disponibili funzioni di gestione della memoria, per assicurare +la compatibilit@`a fra memoria allocata da @command{gawk} e memoria allocata da +un'estensione. + +@item +@emph{Tutta} la memoria passata da @command{gawk} a un'estensione dev'essere +considerata come in sola lettura dall'estensione. + +@item +@emph{Tutta} la memoria passata da un'estensione a @command{gawk} deve +essere ottenuta dalle funzioni di allocazione della memoria previste +dall'API. @command{gawk} @`e responsabile per la gestione di quella memoria e +la libera quando @`e il momento per farlo. + +@item +L'API fornisce informazioni sulla versione di @command{gawk} in +esecuzione, in modo che un'estensione possa verificare la propria compatibilit@`a +con la versione di @command{gawk} da cui @`e stata caricata. + +@item +@`E pi@`u facile iniziare a programmare una nuova estensione usando il +codice predefinito descritto in questo @value{CHAPTER}. Alcune macro nel +file di intestazione @file{gawkapi.h} rendono la cosa pi@`u agevole. + +@item +La distribuzione di @command{gawk} comprende un numero di piccoli ma utili +esempi di estensione. Il progetto @code{gawkextlib} include diverse altre +estensioni, di maggiori dimensioni. +Per chi desideri scrivere un'estensione e metterla a disposizione della +comunit@`a degli utenti di @command{gawk}, il progetto @code{gawkextlib} +@`e il posto adatto per farlo. + +@end itemize + +@c EXCLUDE START +@node Esercizi sulle estensioni +@section Esercizi + +@enumerate +@item +Aggiungere funzioni per rendere disponibili chiamate di sistema come +@code{chown()}, @code{chmod()} e @code{umask()} nelle estensioni che +operano con i file viste +@iftex +nella +@end iftex +@ifnottex +in +@end ifnottex +@ref{Operazioni interne file}. + +@c Idea from comp.lang.awk, February 2015 +@item +Scrivere un analizzatore di input che stampi un prompt se l'input proviene +da un dispositivo che sia un ``terminale''. Si pu@`o usare la funzione +@code{isatty()} per sapere se il file in input @`e un terminale. +(Suggerimento: questa funzione +normalmente usa parecchie risorse quando @`e richiamata; si tenti di chiamarla +una volta sola.) +Il contenuto del prompt dovrebbe provenire da una variabile che sia possibile +impostare a livello di codice @command{awk}. +Si pu@`o inviare il prompt allo standard error. Tuttavia, +per ottenere risultati migliori, @`e meglio aprire un nuovo descrittore di file +(o puntatore a un file) +sul file @file{/dev/tty} e stampare il prompt su quel file, nel caso +in cui lo standard error sia stato ridiretto. + +Perch@'e lo standard error @`e una scelta migliore dello +standard output per scrivere il prompt? +Quale meccanismo di lettura andrebbe sostituito, quello che legge un record +o quello che legge dei semplici byte? + +@item +(Difficile.) +Come si potrebbero gestire degli insiemi di nomi (@dfn{namespaces}) +in @command{gawk}, in modo +che i nomi di funzione presenti in estensioni differenti non siano in conflitto +tra loro? +Chi riesce a trovare uno schema di buona qualit@`a @`e pregato di contattare il +manutentore di @command{gawk}, per metterlo al corrente. + +@item +Si scriva uno script di shell che funga da interfaccia per +l'estensione ``inplace'', vista +@iftex +nella +@end iftex +@ifnottex +in +@end ifnottex +@ref{Esempio di estensione Inplace}, +in modo che il comportamento sia simile a quello del comando @samp{sed -i}. + +@end enumerate +@c EXCLUDE END + +@ifnotinfo +@part @value{PART4}Appendici +@end ifnotinfo + +@ifdocbook + +@ifclear FOR_PRINT +La Parte IV contiene le appendici (come pure le due licenze che proteggono +il codice sorgente di @command{gawk} e questo @value{DOCUMENT}, +rispettivamente) e inoltre il Glossario: +@end ifclear + +@ifset FOR_PRINT +La Parte IV contiene tre appendici, l'ultima delle quali @`e la licenza +che protegge il codice sorgente di @command{gawk}: +@end ifset + +@itemize @value{BULLET} +@item +@ref{Storia del linguaggio} + +@item +@ref{Installazione} + +@ifclear FOR_PRINT +@item +@ref{Note} + +@item +@ref{Concetti fondamentali} + +@item +@ref{Glossario} +@end ifclear + +@item +@ref{Copia} + +@ifclear FOR_PRINT +@item +@ref{Licenza per Documentazione Libera GNU (FDL)} +@end ifclear +@end itemize +@end ifdocbook + +@node Storia del linguaggio +@appendix L'evoluzione del linguaggio @command{awk} + +Questo @value{DOCUMENT} descrive l'implementazione GNU di @command{awk} +conforme alle specifiche POSIX. Molti degli utenti di lunga data di +@command{awk} hanno imparato a programmare in @command{awk} usando +l'implementazione originale di @command{awk} presente nella versione 7 di +Unix. (Questa versione @`e servita da base per la versione Berkeley Unix di +@command{awk}, attraverso la versione 4.3BSD-Reno. Successive versioni di +Berkeley Unix e, per un certo periodo, alcuni sistemi derivati da +4.4BSD-Lite, hanno usato varie versioni di @command{gawk} come loro +@command{awk}.) Questo @value{CHAPTER} descrive in breve l'evoluzione +del linguaggio @command{awk}, facendo riferimento ad altre parti del +@value{DOCUMENT} dove si possono trovare ulteriori informazioni. + +@ifset FOR_PRINT +Per amor di brevit@`a, sono state omesse in questa edizione informazioni +sulla storia delle funzionalit@`a di @command{gawk}. Si possono trovare nella +@uref{http://www.gnu.org/software/gawk/manual/html_node/Feature-History.html, +documentazione online}. +@end ifset + +@menu +* V7/SVR3.1:: Le principali differenze tra V7 e System V + Release 3.1. +* SVR4:: Differenze minori tra System V + Release 3.1 e 4. +* POSIX:: Nuove funzionalit@`a per lo standard POSIX. +* BTL:: Nuove funzionalit@`a dalla versione + di @command{awk} di Brian Kernighan. +* POSIX/GNU:: Le estensioni in @command{gawk} non + previste in @command{awk} POSIX. +* Storia delle funzionalit@`a:: La storia delle funzionalit@`a di + @command{gawk}. +* Estensioni comuni:: Sommario Estensioni comuni. +* Intervalli e localizzazione:: Come le localizzazioni influiscono sugli + intervalli delle espressioni regolari. +* Contributori:: I maggiori contributori a @command{gawk}. +* Sommario della storia:: Sommario della storia. +@end menu + +@node V7/SVR3.1 +@appendixsec Differenze importanti tra V7 e System V Release 3.1 +@cindex @command{awk}, versioni di +@cindex @command{awk}, versioni di, differenze tra V7 e SVR3.1 + +Il liguaggio @command{awk} si @`e evoluto considerevolmente tra Unix versione +7 (1978) e la nuova implementazione disponibile a partire da Unix System V +Release 3.1 (1987). Questa @value{SECTION} riassume le differenze e indica +dove @`e possibile trovare ulteriori dettagli: + +@itemize @value{BULLET} +@item +La necessit@`a di inserire @samp{;} per separare pi@`u regole su una riga +(@pxref{Istruzioni/Righe}) + +@item +Funzioni definite dall'utente e istruzione @code{return} +(@pxref{Funzioni definite dall'utente}) + +@item +L'istruzione @code{delete} (@pxref{Cancellazione}) + +@item +L'istruzione @code{do}-@code{while} +(@pxref{Istruzione do}) + +@item +Le funzioni predefinite @code{atan2()}, @code{cos()}, @code{sin()}, @code{rand()} e +@code{srand()} (@pxref{Funzioni numeriche}) + +@item +Le funzioni predefinite @code{gsub()}, @code{sub()} e @code{match()} +(@pxref{Funzioni per stringhe}) + +@item +Le funzioni predefinite @code{close()} e @code{system()} +(@pxref{Funzioni di I/O}) + +@item +Le variabili predefinite @code{ARGC}, @code{ARGV}, @code{FNR}, @code{RLENGTH}, +@code{RSTART} e @code{SUBSEP} (@pxref{Variabili predefinite}) + +@item +Possibilit@`a di modificare @code{$0} (@pxref{Cambiare i campi}) + +@item +L'espressione condizionale che fa uso dell'operatore ternario @samp{?:} +(@pxref{Espressioni condizionali}) + +@item +L'espressione @samp{@var{indice} in @var{vettore}} esterna alle istruzioni +@code{for} (@pxref{Visitare elementi}) + +@item +L'operatore esponenziale @samp{^} +(@pxref{Operatori aritmetici}) e il relativo operatore di assegnamento +@samp{^=} (@pxref{Operatori di assegnamento}) + +@item +Precedenze tra operatori compatibili con quelle del linguaggio C, che +rendono non funzionanti alcuni vecchi programmi @command{awk} (@pxref{Precedenza}) + +@item +La possibilit@`a di usare @dfn{regexp} come valori di @code{FS} +(@pxref{Separatori di campo}) e come +terzo argomento per la funzione @code{split()} +(@pxref{Funzioni per stringhe}), invece di usare solo il primo carattere +di @code{FS} + +@item +@dfn{Regexp} dinamiche come operandi degli operatori @samp{~} e @samp{!~} +(@pxref{Espressioni regolari calcolate}) + +@item +Le sequenze di protezione @samp{\b}, @samp{\f} e @samp{\r} +(@pxref{Sequenze di protezione}) + +@item +La ridirezione dell'input per la funzione @code{getline} +(@pxref{Getline}) + +@item +La possibilit@`a di avere pi@`u regole @code{BEGIN} ed @code{END} +(@pxref{BEGIN/END}) + +@item +Vettori multidimensionali +(@pxref{Vettori multidimensionali}) +@end itemize + +@node SVR4 +@appendixsec Differenze tra le versioni System V Release 3.1 e SVR4 + +@cindex @command{awk}, versioni di, differenze tra SVR3.1 e SVR4 +La versione per Unix System V Release 4 (1989) di @command{awk} ha aggiunto +queste funzionalit@`a (alcune delle quali introdotte da @command{gawk}): + +@itemize @value{BULLET} +@item +Il vettore @code{ENVIRON} (@pxref{Variabili predefinite}) +@c gawk and MKS awk + +@item +La possibilit@`a di specificare pi@`u opzioni @option{-f} sulla riga di comando +(@pxref{Opzioni}) +@c MKS awk +@c Mortice Kern Systems, ditta produttrice di una versione commerciale di awk + +@item +L'opzione @option{-v} per assegnare variabili prima di iniziare +l'esecuzione del programma +(@pxref{Opzioni}) +@c GNU, Bell Laboratories & MKS together + +@item +La notazione @option{--} per indicare la fine delle opzioni sulla riga di +comando + +@item +Le sequenze di protezione @samp{\a}, @samp{\v} e @samp{\x} +(@pxref{Sequenze di protezione}) +@c GNU, for ANSI C compat + +@item +Un valore di ritorno definito per la funzione predefinita @code{srand()} +(@pxref{Funzioni numeriche}) + +@item +Le funzioni predefinite per stringhe @code{toupper()} e @code{tolower()} +per la conversione maiuscolo/minuscolo +(@pxref{Funzioni per stringhe}) + +@item +Una specificazione pi@`u accurata per la lettera @samp{%c} di controllo del +formato nella funzione @code{printf} +(@pxref{Lettere di controllo}) + +@item +La capacit@`a di decidere dinamicamente la larghezza di un campo e la +precisione da usare (@code{"%*.*d"}) nella lista degli argomenti passati a +@code{printf} e @code{sprintf()} +(@pxref{Lettere di controllo}) + +@item +L'uso di costanti @dfn{regexp}, p.es. @code{/pippo/}, come espressioni, +che equivalgono a usare l'operatore di ricerca di una +corrispondenza, p.es. @samp{$0 ~ /pippo/} +(@pxref{Usare le costanti @dfn{regexp}}) + +@item +Gestione di sequenze di protezione nell'assegnamento di variabili +effettuato tramite la riga di comando +(@pxref{Opzioni di assegnamento}) +@end itemize + +@node POSIX +@appendixsec Differenze tra versione SVR4 e POSIX di @command{awk} +@cindex @command{awk}, versioni di, differenze tra SVR4 e POSIX @command{awk} +@cindex POSIX @command{awk}, differenze tra versioni @command{awk} + +Lo standard POSIX Command Language and Utilities per @command{awk} (1992) +ha introdotto le seguenti modifiche al linguaggio: + +@itemize @value{BULLET} +@item +L'uso dell'opzione @option{-W} per opzioni specifiche a una data +implementazione +(@pxref{Opzioni}) + +@item +L'uso di @code{CONVFMT} per controllare la conversione di numeri +in stringhe (@pxref{Conversione}) + +@item +Il concetto di stringa numerica e regole di confronto pi@`u precise da seguire +al riguardo (@pxref{Tipi di variabile e confronti}) + +@item +L'uso di variabili predefinite come nomi di parametri delle funzioni @`e vietato +(@pxref{Sintassi delle definizioni}) + +@item +Una documentazione pi@`u completa di molte tra le funzionalit@`a del linguaggio +precedentemente non documentate +@end itemize + +Nel 2012, un certo numero di estensioni che erano gi@`a comunemente +disponibili da parecchi anni sono state finalmente aggiunte allo standard +POSIX. Ecco l'elenco: + +@itemize @value{BULLET} +@item +La funzione predefinita @code{fflush()} per forzare la scrittura dei buffer +in output +(@pxref{Funzioni di I/O}) + +@item +L'istruzione @code{nextfile} +(@pxref{Istruzione nextfile}) + +@item +La possibilit@`a di eliminare completamente un vettore con l'istruzione +@samp{delete @var{vettore}} +(@pxref{Cancellazione}) + +@end itemize + +@xref{Estensioni comuni} per una lista delle estensioni comuni +non previste nello standard POSIX. + +Lo standard POSIX 2008 @`e reperibile online a: +@url{http://www.opengroup.org/onlinepubs/9699919799/}. + + +@node BTL +@appendixsec Estensioni nell'@command{awk} di Brian Kernighan + +@cindex @command{awk}, versioni di, si veda anche Brian Kernighan, @command{awk} di +@cindex estensioni, Brian Kernighan @command{awk} +@cindex Brian Kernighan, @command{awk} di, estensioni +@cindex Kernighan, Brian +Brian Kernighan +ha reso disponibile la sua versione nel suo sito. +(@pxref{Altre versioni}). + +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} descrive estensioni comuni disponibili per la +prima volta nella sua versione di @command{awk}: + +@itemize @value{BULLET} +@item +Gli operatori @samp{**} e @samp{**=} +(@pxref{Operatori aritmetici} +e +@ref{Operatori di assegnamento}) + +@item +L'uso di @code{func} come abbreviazione di @code{function} +(@pxref{Sintassi delle definizioni}) + +@item +La funzione predefinita @code{fflush()} per forzare la scrittura dei buffer +in output +(@pxref{Funzioni di I/O}) + +@ignore +@item +The @code{SYMTAB} array, that allows access to @command{awk}'s internal symbol +table. This feature was never documented for his @command{awk}, largely because +it is somewhat shakily implemented. For instance, you cannot access arrays +or array elements through it +@end ignore +@end itemize + +@xref{Estensioni comuni} per una lista completa delle estensioni +disponibile nel suo @command{awk}. + +@node POSIX/GNU +@appendixsec Estensioni di @command{gawk} non in POSIX @command{awk} + +@cindex modalit@`a compatibile di (@command{gawk}), estensioni nella +@cindex estensioni nella modalit@`a compatibile di (@command{gawk}) +@cindex estensioni, in @command{gawk}, non in POSIX @command{awk} +@cindex POSIX, estensioni @command{gawk} non incluse in +L'implementazione GNU di @command{gawk} aggiunge molte funzionalit@`a. +Queste possono essere disabilitate completamente sia con l'opzione +@option{--traditional} che con l'opzione +@option{--posix} +(@pxref{Opzioni}). + +Alcune funzionalit@`a sono state introdotte e successivamente tolte +con il passare del tempo. +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} +sintetizza le ulteriori funzionalit@`a rispetto a POSIX @command{awk} che sono +presenti nella versione corrente di @command{gawk}. + +@itemize @value{BULLET} + +@item +Ulteriori variabili predefinite: + +@itemize @value{MINUS} +@item +Le variabili +@code{ARGIND}, +@code{BINMODE}, +@code{ERRNO}, +@code{FIELDWIDTHS}, +@code{FPAT}, +@code{IGNORECASE}, +@code{LINT}, +@code{PROCINFO}, +@code{RT} +e +@code{TEXTDOMAIN} +(@pxref{Variabili predefinite}) +@end itemize + +@item +File speciali verso cui ridirigere l'I/O: + +@itemize @value{MINUS} +@item +I file @file{/dev/stdin}, @file{/dev/stdout}, @file{/dev/stderr} e i +@value{FNS} speciali @file{/dev/fd/@var{N}} +(@pxref{File speciali}) + +@item +I file speciali @file{/inet}, @file{/inet4} e @file{/inet6} per +interagire con la rete TCP/IP usando @samp{|&} per specificare quale +versione usare del protocollo IP +(@pxref{Reti TCP/IP}) +@end itemize + +@item +Differenze e/o aggiunte al linguaggio: + +@itemize @value{MINUS} +@item +La sequenza di protezione @samp{\x} +(@pxref{Sequenze di protezione}) + +@item +Supporto completo per @dfn{regexp} sia POSIX che GNU +@iftex +(@pxrefil{Espressioni regolari}) +@end iftex +@ifnottex +(@pxref{Espressioni regolari}) +@end ifnottex + +@item +La possibilit@`a che @code{FS} e il terzo +argomento di @code{split()} siano la stringa nulla +(@pxref{Campi di un solo carattere}) + +@item +La possibilit@`a che @code{RS} sia una @dfn{regexp} +(@pxref{Record}) + +@item +La possibilit@`a di usare costanti ottali ed esadecimali nei programmi +scritti in @command{awk} +(@pxref{Numeri non-decimali}) + +@item +L'operatore @samp{|&} per poter effettuare I/O bidirezionale verso un +coprocesso +(@pxref{I/O bidirezionale}) + +@item +Chiamate indirette di funzione +(@pxref{Chiamate indirette}) + +@item +La possibilit@`a di ignorare directory specificate sulla riga di comando, +emettendo un messaggio di avvertimento +(@pxref{Directory su riga di comando}) + +@item +Errori in output usando @code{print} e @code{printf} non provocano +necessariamente la fine del programma +(@pxref{Continuazione dopo errori}) +@end itemize + +@item +Nuove parole chiave: + +@itemize @value{MINUS} +@item +I criteri di ricerca speciali @code{BEGINFILE} ed @code{ENDFILE} +(@pxref{BEGINFILE/ENDFILE}) + +@item +L'istruzione @code{switch} +(@pxref{Istruzione switch}) +@end itemize + +@item +Differenze in funzioni standard di @command{awk}: + +@itemize @value{MINUS} +@item +Il secondo argomento opzionale di @code{close()} che consente di chiudere +un solo lato dell'I/O di una @dfn{pipe} bidirezionale aperta verso un +coprocesso (@pxref{I/O bidirezionale}) + +@item +Aderenza allo standard POSIX per le funzioni @code{gsub()} e @code{sub()} +se @`e stata specificata l'opzione @option{--posix} + +@item +La funzione @code{length()} accetta come argomento il nome di un vettore +e restituisce il numero di elementi nel vettore +(@pxref{Funzioni per stringhe}) + +@item +Il terzo argomento opzionale della funzione @code{match()} +per contenere eventuali sottoespressioni individuate all'interno di una +@dfn{regexp} +(@pxref{Funzioni per stringhe}) + +@item +Specificatori posizionali nei formati di @code{printf} per facilitare +le traduzioni di messaggi +(@pxref{Ordinamento di printf}) + +@item +L'aggiunta di un quarto argomento opzionale alla funzione @code{split()}, +per designare un vettore che contenga il testo dei separatori di campo +(@pxref{Funzioni per stringhe}) +@end itemize + +@item +Ulteriori funzioni presenti solo in @command{gawk}: + +@itemize @value{MINUS} +@item +Le funzioni @code{gensub()}, @code{patsplit()} e @code{strtonum()} +per una gestione di testi pi@`u potente +(@pxref{Funzioni per stringhe}) + +@item +Le funzioni @code{asort()} e @code{asorti()} per l'ordinamento di vettori +(@pxref{Ordinamento di vettori}) + +@item +Le funzioni @code{mktime()}, @code{systime()} e @code{strftime()} +per lavorare con date e ore +(@pxref{Funzioni di tempo}) + +@item +Le funzioni +@code{and()}, +@code{compl()}, +@code{lshift()}, +@code{or()}, +@code{rshift()} +e +@code{xor()} +per la manipolazione a livello di bit +(@pxref{Funzioni a livello di bit}) +@c In 4.1, and(), or() and xor() grew the ability to take > 2 arguments + +@item +La funzione @code{isarray()} per controllare se una variabile @`e un vettore +oppure no +(@pxref{Funzioni per i tipi}) + +@item +Le funzioni @code{bindtextdomain()}, @code{dcgettext()} +e @code{dcngettext()} per l'internazionalizzazione +(@pxref{I18N per programmatore}) + +@item +La funzione @code{intdiv()} per effettuare divisioni a numeri interi e +ottenere il resto della divisione +(@pxref{Funzioni numeriche}) +@end itemize + +@item +Modifiche e/o aggiunte alle opzioni della riga di comando: + +@itemize @value{MINUS} +@item +La variabile d'ambiente @env{AWKPATH} per specificare un percorso di ricerca +per l'opzione @option{-f} della riga di comando +(@pxref{Opzioni}) + +@item +La variabile d'ambiente @env{AWKLIBPATH} per specificare un percorso di ricerca +per l'opzione @option{-l} della riga di comando +(@pxref{Opzioni}) + +@item +Le opzioni brevi +@option{-b}, +@option{-c}, +@option{-C}, +@option{-d}, +@option{-D}, +@option{-e}, +@option{-E}, +@option{-g}, +@option{-h}, +@option{-i}, +@option{-l}, +@option{-L}, +@option{-M}, +@option{-n}, +@option{-N}, +@option{-o}, +@option{-O}, +@option{-p}, +@option{-P}, +@option{-r}, +@option{-s}, +@option{-S}, +@option{-t} +e +@option{-V} +. Inoltre, la +possibilit@`a di usare opzioni in formato lungo (stile GNU) che iniziano +con @option{--} +e le opzioni lunghe +@option{--assign}, +@option{--bignum}, +@option{--characters-as-bytes}, +@option{--copyright}, +@option{--debug}, +@option{--dump-variables}, +@option{--exec}, +@option{--field-separator}, +@option{--file}, +@option{--gen-pot}, +@option{--help}, +@option{--include}, +@option{--lint}, +@option{--lint-old}, +@option{--load}, +@option{--non-decimal-data}, +@option{--optimize}, +@option{--no-optimize}, +@option{--posix}, +@option{--pretty-print}, +@option{--profile}, +@option{--re-interval}, +@option{--sandbox}, +@option{--source}, +@option{--traditional}, +@option{--use-lc-numeric}, +and +@option{--version} +(@pxref{Opzioni}). +@end itemize + +@c new ports + +@item +Il supporto per i seguenti sistemi obsoleti @`e stato rimosso dal codice +sorgente e dalla documentazione di @command{gawk} @value{PVERSION} 4.0: + +@c nested table +@itemize @value{MINUS} +@item +Amiga + +@item +Atari + +@item +BeOS + +@item +Cray + +@item +MIPS RiscOS + +@item +MS-DOS con il compilatore Microsoft + +@item +MS-Windows con il compilatore Microsoft + +@item +NeXT + +@item +SunOS 3.x, Sun 386 (Road Runner) + +@item +Tandem (non-POSIX) + +@item +Compilatore pre-standard VAX C per VAX/VMS + +@item +GCC per VAX e Alpha non @`e stato verificato da parecchio tempo. + +@end itemize + +@item +Il supporto per i seguenti sistemi obsoleti @`e stato rimosso dal codice +di @command{gawk} @value{PVERSION} 4.1: + +@c nested table +@itemize @value{MINUS} +@item +Ultrix +@end itemize + +@item +Il supporto per i seguenti sistemi obsoleti @`e stato rimosso dal codice +sorgente e dalla documentazione di +@command{gawk} @value{PVERSION} 4.2: + +@c nested table +@itemize @value{MINUS} +@item +MirBSD + +@item +GNU/Linux su Alpha +@end itemize + +@end itemize + +@c XXX ADD MORE STUFF HERE + + +@c This does not need to be in the formal book. +@ifclear FOR_PRINT +@node Storia delle funzionalit@`a +@appendixsec Storia delle funzionalit@`a di @command{gawk} + +@ignore +See the thread: +https://groups.google.com/forum/#!topic/comp.lang.awk/SAUiRuff30c +This motivated me to add this section. +@end ignore + +@ignore +I've tried to follow this general order, esp.@: for the 3.0 and 3.1 sections: + variables + special files + language changes (e.g., hex constants) + differences in standard awk functions + new gawk functions + new keywords + new command-line options + behavioral changes + new ports +Within each category, be alphabetical. +@end ignore + +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} descrive le funzionalit@`a in @command{gawk} +in aggiunta a quelle di POSIX @command{awk}, +nell'ordine in cui sono state rese disponibili in @command{gawk}. + +La versione 2.10 di @command{gawk} ha introdotto le seguenti funzionalit@`a: + +@itemize @value{BULLET} +@item +La variabile d'ambiente @env{AWKPATH} per specificare un percorso di ricerca +per l'opzione @option{-f} della riga di comando +(@pxref{Opzioni}) + +@item +La variabile @code{IGNORECASE} e i suoi effetti +(@pxref{Maiuscolo-Minuscolo}). + +@item +I file @file{/dev/stdin}, @file{/dev/stdout}, @file{/dev/stderr} e i +@value{FNS} speciali @file{/dev/fd/@var{N}} +(@pxref{File speciali}) +@end itemize + +La versione 2.13 di @command{gawk} ha ha introdotto le seguenti funzionalit@`a: + +@itemize @value{BULLET} +@item +La variabile @code{FIELDWIDTHS} e i suoi effetti +(@pxref{Dimensione costante}). + +@item +Le funzioni predefinite @code{systime()} e @code{strftime()} per ottenere +e stampare data e ora +(@pxref{Funzioni di tempo}). + +@item +Ulteriori opzioni dalla riga di comando +(@pxref{Opzioni}): + +@itemize @value{MINUS} +@item +L'opzione @option{-W lint} per fornire controlli su possibili errori e per +la portabilit@`a, sia a livello di codice sorgente che in fase di esecuzione. + +@item +L'opzione @option{-W compat} per inibire le estensioni GNU. + +@item +L'opzione @option{-W posix} per richiedere una stretta aderenza allo +standard POSIX. +@end itemize +@end itemize + +La versione 2.14 di @command{gawk} ha introdotto le seguenti funzionalit@`a: + +@itemize @value{BULLET} +@item +L'istruzione @code{next file} per passare immediatamente al successivo +@value{DF} (@pxref{Istruzione nextfile}). +@end itemize + +La versione 2.15 di @command{gawk} ha introdotto le seguenti funzionalit@`a: + +@itemize @value{BULLET} +@item +Nuove variabili (@pxref{Variabili predefinite}): + +@itemize @value{MINUS} +@item +@code{ARGIND}, che permette di controllare la posizione di @code{FILENAME} +nel vettore @code{ARGV}. + +@item +@code{ERRNO}, che contiene il messaggio di errore del sistema quando +@code{getline} restituisce @minus{}1 o @code{close()} non termina con successo. +@end itemize + +@item +I @value{FNS} speciali @file{/dev/pid}, @file{/dev/ppid}, @file{/dev/pgrpid} +e @file{/dev/user}. Questo supporto @`e stato rimosso in seguito. + +@item +La possibilit@`a di cancellare un intero vettore in una sola istruzione +con @samp{delete @var{vettore}} +(@pxref{Cancellazione}). + +@item +Modifiche nelle opzioni della riga di comando +(@pxref{Opzioni}): + +@itemize @value{MINUS} +@item +La possibilit@`a di usare opzioni in formato lungo (in stile GNU) che iniziano +con @option{--}. + +@item +L'opzione @option{--source} per combinare codice sorgente immesso nella riga +di comando e codice sorgente proveniente da file di libreria. +@end itemize +@end itemize + +La versione 3.0 di @command{gawk} ha introdotto le seguenti funzionalit@`a: + +@itemize @value{BULLET} +@item +Variabili nuove o modificate: + +@itemize @value{MINUS} +@item +@code{IGNORECASE} modificato, diventa applicabile al confronto tra stringhe, +come pure alle operazioni su @dfn{regexp} +(@pxref{Maiuscolo-Minuscolo}). + +@item +@code{RT}, che contiene il testo in input che @`e stato individuato da @code{RS} +(@pxref{Record}). +@end itemize + +@item +Supporto completo sia per le @dfn{regexp} POSIX sia per quelle GNU +@iftex +(@pxrefil{Espressioni regolari}). +@end iftex +@ifnottex +(@pxref{Espressioni regolari}). +@end ifnottex + +@item +La funzione @code{gensub()} per migliorare la manipolazione di testi +(@pxref{Funzioni per stringhe}). + +@item +La funzione @code{strftime()} prevede un formato di data e ora di default, +in modo da poter essere chiamata senza alcun argomento. +(@pxref{Funzioni di tempo}). + +@item +La possibilit@`a che @code{FS} e il terzo argomento della funzione +@code{split()} siano delle stringhe nulle +(@pxref{Campi di un solo carattere}). + +@item +La possibilit@`a che @code{RS} sia una @dfn{regexp} +(@pxref{Record}). + +@item +L'istruzione @code{next file} @`e diventata @code{nextfile} +(@pxref{Istruzione nextfile}). + +@item +La funzione @code{fflush()} di +BWK @command{awk} +(BWK allora lavorava ai Bell Laboratories; +@pxref{Funzioni di I/O}). + +@item +Nuove opzioni della riga di comando: + +@itemize @value{MINUS} +@item +L'opzione @option{--lint-old} per +ottenere messaggi relativi a costrutti non disponibili +nell'implementazione di @command{awk} per Unix Version 7 +(@pxref{V7/SVR3.1}). + +@item +L'opzione @option{-m} da BWK @command{awk}. (Brian lavorava +ancora ai Bell Laboratories all'epoca.) Quest'opzione @`e stata in seguito +rimossa, sia dal suo @command{awk} che da @command{gawk}. + +@item +L'opzione @option{--re-interval} per consentire di specificare +espressioni di intervallo nelle @dfn{regexp} +(@pxref{Operatori di espressioni regolari}). + +@item +L'opzione @option{--traditional} aggiunta come maniera pi@`u intuitiva +per richiedere l'opzione +@option{--compat} (@pxref{Opzioni}). +@end itemize + +@item +L'uso di GNU Autoconf per controllare il processo di configurazione +(@pxref{Installazione veloce}). + +@item +Supporto per Amiga. +Questo supporto @`e stato rimosso in seguito. + +@end itemize + +La versione 3.1 di @command{gawk} ha introdotto le seguenti funzionalit@`a: + +@itemize @value{BULLET} +@item +Nuove variabili +(@pxref{Variabili predefinite}): + +@itemize @value{MINUS} +@item +@code{BINMODE}, per sistemi non aderenti allo standard POSIX, +che consente I/O binario per file in input e/o output +(@pxref{Uso su PC}). + +@item +@code{LINT}, che controlla dinamicamente gli avvertimenti emessi da @dfn{lint}. + +@item +@code{PROCINFO}, un vettore che fornisce informazioni correlate con il +processo in esecuzione. + +@item +@code{TEXTDOMAIN}, per impostare il dominio testuale in cui internazionalizzare +un'applicazione (@pxref{Internazionalizzazione}). +@end itemize + +@item +La possibilit@`a di usare costanti ottali ed esadecimali nel codice +sorgente di programmi @command{awk}. +(@pxref{Numeri non-decimali}). + +@item +L'operatore @samp{|&} per effettuare I/O bidirezionale verso un +coprocesso +(@pxref{I/O bidirezionale}). + +@item +I file speciali @file{/inet} per interagire con reti TCP/IP usando @samp{|&} +(@pxref{Reti TCP/IP}). + +@item +Il secondo argomento opzionale della funzione @code{close()} per permettere di +chiudere uno dei lati di una @dfn{pipe} bidirezionale aperta con un coprocesso +(@pxref{I/O bidirezionale}). + +@item +Il terzo argomento opzionale della funzione @code{match()} per +avere a disposizione le diverse sottoespressioni individuate all'interno +di una @dfn{regexp} +(@pxref{Funzioni per stringhe}). + +@item +Specificatori posizionali nelle stringhe di formato di @code{printf} per +facilitare la traduzione di messaggi +(@pxref{Ordinamento di printf}). + +@item +Alcune nuove funzioni predefinite: + +@itemize @value{MINUS} +@item +Le funzioni @code{asort()} e @code{asorti()} per l'ordinamento di vettori +(@pxref{Ordinamento di vettori}). + +@item +Le funzioni @code{bindtextdomain()}, @code{dcgettext()} e @code{dcngettext()} +per l'internationalizzazione +(@pxref{I18N per programmatore}). + +@item +La funzione @code{extension()} e la possibilit@`a di aggiungere +nuove funzioni predefinite dinamicamente +@iftex +(@pxrefil{Estensioni dinamiche}). +@end iftex +@ifnottex +(@pxref{Estensioni dinamiche}). +@end ifnottex + +@item +La funzione @code{mktime()} per generare date e ore +(@pxref{Funzioni di tempo}). + +@item +Le funzioni @code{and()}, @code{or()}, @code{xor()}, @code{compl()}, +@code{lshift()}, @code{rshift()} e @code{strtonum()} +(@pxref{Funzioni a livello di bit}). +@end itemize + +@item +@cindex @code{next file} statement +Il supporto per @samp{next file} scritto come due parole @`e stato rimosso +completamente +(@pxref{Istruzione nextfile}). + +@item +Ulteriori opzioni sulla riga di comando +(@pxref{Opzioni}): + +@itemize @value{MINUS} +@item +L'opzione @option{--dump-variables} per stampare una lista di tutte le +variabili globali. + +@item +L'opzione @option{--exec}, da usare in script CGI [Common Gateway Interface]. + +@item +L'opzione della riga di comando @option{--gen-po} e l'uso di un trattino +basso a inizio stringa, per segnalare stringhe che dovrebbero essere tradotte +(@pxref{Estrazione di stringhe}). + +@item +L'opzione @option{--non-decimal-data} per consentire di avere dati in input +di tipo non decimale +(@pxref{Dati non decimali}). + +@item +L'opzione @option{--profile} e @command{pgawk}, la +versione profilatrice di @command{gawk}, per produrre profili di esecuzione +di programmi @command{awk} +(@pxref{Profilare}). + +@item +L'opzione @option{--use-lc-numeric} per richiedere a @command{gawk} +di usare il carattere di separazione decimale proprio della localizzazione +nell'elaborazione dei dati in input +(@pxref{Conversione}). +@end itemize + +@item +L'uso di GNU Automake a supporto della standardizzazione del processo +di configurazione +(@pxref{Installazione veloce}). + +@item +L'uso di GNU @command{gettext} per i messaggi emessi da @command{gawk} +(@pxref{Gawk internazionalizzato}). + +@item +Supporto per BeOS. Rimosso in seguito. + +@item +Supporto per Tandem. Rimosso in seguito. + +@item +La versione per Atari ufficialmente non @`e pi@`u supportata e in seguito +@`e stata completamente rimossa. + +@item +Modifiche al codice sorgente per usare definizioni di funzione secondo lo +stile di codifica dello standard ISO C. + +@item +Aderenza alla specifica POSIX per le funzioni @code{sub()} e @code{gsub()} +(@pxref{Dettagli ostici}). + +@item +La funzione @code{length()} @`e stata estesa per accettare un vettore come +argomento, e restituire in tal caso il numero di elementi nel vettore +(@pxref{Funzioni per stringhe}). + +@item +La funzione @code{strftime()} accetta un terzo argomento per +dare la possibilit@`a di stampare data e ora nel formato UTC +(@pxref{Funzioni di tempo}). +@end itemize + +La versione 4.0 di @command{gawk} ha introdotto le seguenti funzionalit@`a: + +@itemize @value{BULLET} + +@item +Aggiunta di variabili: + +@itemize @value{MINUS} +@item +@code{FPAT}, che permette di specificare una @dfn{regexp} che individua +i campi, invece che individuare il separatore tra i campi +(@pxref{Separazione in base al contenuto}). + +@item +Se esiste l'elemento di vettore @code{PROCINFO["sorted_in"]}, il ciclo +@samp{for(indice in pippo)} ordina +gli indici, prima di iniziare il ciclo. Il valore di questo elemento +permette di controllare l'ordinamento degli indici prima di iniziare il +ciclo che li visita tutti +(@pxref{Controllare visita}). + +@item +@code{PROCINFO["strftime"]}, che contiene la stringa di formato +di default per @code{strftime()} +(@pxref{Funzioni di tempo}). +@end itemize + +@item +I file speciali @file{/dev/pid}, @file{/dev/ppid}, @file{/dev/pgrpid} +e @file{/dev/user} sono stati rimossi. + +@item +Il supporto per IPv6 @`e stato aggiunto attraverso il file speciale +@file{/inet6}. +Il file speciale @file{/inet4} consente di operare con IPv4 e @file{/inet} +opera con il default di sistema, che probabilmente @`e IPv4 +(@pxref{Reti TCP/IP}). + +@item +L'uso delle sequenze di protezione @samp{\s} e @samp{\S} nelle espressioni +regolari +(@pxref{Operatori di @dfn{regexp} GNU}). + +@item +Le espressioni di intervallo sono consentite per default nelle espressioni +regolari +(@pxref{Operatori di espressioni regolari}). + +@item +La classi di caratteri POSIX sono consentite anche se si @`e specificata +l'opzione @option{--traditional} +(@pxref{Operatori di espressioni regolari}). + +@item +@code{break} e @code{continue} non sono pi@`u consentiti fuori da un ciclo, +anche se si @`e specificata l'opzione @option{--traditional} +(@pxref{Istruzione break} e anche la +@ref{Istruzione continue}). + +@item +@code{fflush()}, @code{nextfile} e @samp{delete @var{array}} +sono consentite anche se @`e stata specificata l'opzione @option{--posix} o +@option{--traditional}, poich@'e questi costrutti sono ora inclusi +nello standard POSIX. + +@item +Un terzo argomento facoltativo per le funzioni @code{asort()} e @code{asorti()} +permette di specificare il tipo di ordinamento desiderato +(@pxref{Funzioni per stringhe}). + +@item +Il comportamento di @code{fflush()} @`e stato modificato per corrispondere +a quello di BWK @command{awk} +e per lo standard POSIX; ora sia @samp{fflush()} che @samp{fflush("")} +forzano la scrittura di tutte le ridirezioni in output aperte +(@pxref{Funzioni di I/O}). + +@item +La funzione @code{isarray()} +determina se un elemento @`e un vettore oppure no +per rendere possibile la visita di vettori di vettori +(@pxref{Funzioni per i tipi}). + +@item +La funzione @code{patsplit()} che +fornisce le stesse funzionalit@`a di @code{FPAT}, per suddividere delle stringhe +(@pxref{Funzioni per stringhe}). + +@item +Un quarto argomento opzionale per la funzione @code{split()}, +che indica un vettore destinato a contenere i valori dei separatori +(@pxref{Funzioni per stringhe}). + +@item +Vettori di vettori +(@pxref{Vettori di vettori}). + +@item +I criteri di ricerca speciali @code{BEGINFILE} ed @code{ENDFILE} +(@pxref{BEGINFILE/ENDFILE}). + +@item +Chiamate indirette di funzioni +(@pxref{Chiamate indirette}). + +@item +Le istruzioni @code{switch} / @code{case} sono disponibili per default +(@pxref{Istruzione switch}). + +@item +Modifiche nelle opzioni della riga di comando +(@pxref{Opzioni}): + +@itemize @value{MINUS} +@item +Le opzioni @option{-b} e @option{--characters-as-bytes}, +che impediscono che @command{gawk} tratti l'input come composto da una +stringa di caratteri multibyte. + +@item +Rimozione delle opzioni ridondanti (in notazione lunga) @option{--compat}, +@option{--copyleft} e @option{--usage}. + +@item +L'opzione @option{--gen-po} @`e stata finalmente rinominata +@option{--gen-pot} per correttezza. + +@item +L'opzione @option{--sandbox} che disabilita alcune funzionalit@`a [per operare +in un ambiente "protetto"]. + +@item +Tutte le opzioni in notazione lunga hanno acquisito opzioni corrispondenti +in notazione breve, per poter essere usate negli script di shell @samp{#!}. +@end itemize + +@item +I nomi di directory che appaiono sulla riga di comando generano adesso +un messaggio di errore, ma non interrompono l'elaborazione, a meno che non +siano state specificate le opzioni @option{--posix} o @option{--traditional} +(@pxref{Directory su riga di comando}). + +@item +Il codice interno di @command{gawk} @`e stato riscritto, aggiungendo la +versione per il debug @command{dgawk}, +con un possibile miglioramento nei tempi di esecuzione +@iftex +(@pxrefil{Debugger}). +@end iftex +@ifnottex +(@pxref{Debugger}). +@end ifnottex + +@item +In aderenza agli standard di codifica GNU, le estensioni dinamiche devono +definire un simbolo globale che indica che sono compatibili con la +licenza GPL +(@pxref{Licenza delle estensioni}). + +@item +In modalit@`a POSIX, i confronti tra stringhe usano le funzioni di +libreria @code{strcoll()} / @code{wcscoll()} +(@pxref{Confronto POSIX di stringhe}). + +@item +L'opzione per usare @dfn{socket} in maniera @dfn{raw} (nativa) @`e stata +rimossa, perch@'e non era mai stata implementata +(@pxref{Reti TCP/IP}). + +@item +Intervalli nella forma @samp{[d-h]} sono elaborati come se fossero scritti +nella localizzazione C, a prescindere da che tipo di @dfn{regexp} @`e usata, +anche se era stata specificata l'opzione +@option{--posix} +(@pxref{Intervalli e localizzazione}). + +@item +@`E stato rimosso il supporto per i seguenti sistemi: + +@itemize @value{MINUS} +@item +Atari + +@item +Amiga + +@item +BeOS + +@item +Cray + +@item +MIPS RiscOS + +@item +MS-DOS con Compilatore Microsoft + +@item +MS-Windows con Compilatore Microsoft + +@item +NeXT + +@item +SunOS 3.x, Sun 386 (Road Runner) + +@item +Tandem (non-POSIX) + +@item +Compilatore pre-standard VAX C per VAX/VMS +@end itemize +@end itemize + +La versione 4.1 di @command{gawk} ha introdotto le seguenti funzionalit@`a: + +@itemize @value{BULLET} + +@item +Tre nuovi vettori: +@code{SYMTAB}, @code{FUNCTAB} e @code{PROCINFO["identifiers"]} +(@pxref{Variabili auto-assegnate}). + +@item +I tre comandi eseguibili @command{gawk}, @command{pgawk} e @command{dgawk}, +sono diventati uno solo, con il solo nome @command{gawk}. Di conseguenza +le opzioni sulla riga di comando sono state modificate. + +@item +Modifiche delle opzioni da riga di comando +(@pxref{Opzioni}): + +@itemize @value{MINUS} +@item +L'opzione @option{-D} attiva il debugger. + +@item +Le opzioni @option{-i} e @option{--include} +caricano dei file di libreria @command{awk}. + +@item +Le opzioni @option{-l} e @option{--load} caricano estensioni dinamiche +compilate. + +@item +Le opzioni @option{-M} e @option{--bignum} abilitano la libreria MPFR per +il calcolo con un numero arbitrario di cifre significative. + +@item +L'opzione @option{-o} serve solo a ottenere in output una stampa formattata +elegantemente del programma da eseguire. + +@item +L'opzione @option{-p} @`e usata per "profilare" l'esecuzione del programma. + +@item +L'opzione @option{-R} @`e stata rimossa. +@end itemize + +@item +Supporto per il calcolo ad alta precisione con MPFR +(@pxref{Calcolo con precisione arbitraria}). + +@item +Le funzioni @code{and()}, @code{or()} e @code{xor()} sono state modificate +per ammettere un numero qualsiasi di argomenti, con un minimo di due +(@pxref{Funzioni a livello di bit}). + + +@item +L'interfaccia che rende possibile l'estensione dinamica @`e stata rifatta +completamente +@iftex +(@pxrefil{Estensioni dinamiche}). +@end iftex +@ifnottex +(@pxref{Estensioni dinamiche}). +@end ifnottex + +@item +La funzione @code{getline} ridiretta @`e stata resa possibile all'interno di +@code{BEGINFILE} ed @code{ENDFILE} +(@pxref{BEGINFILE/ENDFILE}). + +@item +Il comando @code{where} @`e stato aggiunto al debugger +(@pxref{Stack di esecuzione}). + +@item +Il supporto per Ultrix @`e stato rimosso. + +@end itemize + +La versione 4.2 ha introdotto le seguenti funzionalit@`a: + +@itemize @bullet +@item +Differenze apportate alle variabili di ambiente (@code{ENVIRON}) sono riflesse in quelle +rese disponibili a @command{gawk} e in quelle di programmi che siano da esso richiamati. +@xref{Variabili auto-assegnate}. + +@item +L'opzione @option{--pretty-print} non esegue pi@`u, dopo averlo stampato, +il programma @command{awk}. +@xref{Opzioni}. + +@item +Il programma @command{igawk} e le relative pagine di manuale non sono +pi@`u installati come parte dell'installazione di @command{gawk}. +@xref{Programma igawk}. + +@item +La funzione @code{intdiv()}. +@xref{Funzioni numeriche}. + +@item +Il massimo numero di cifre esadecimali permesse nelle sequenze di +protezione @samp{\x} @`e ora limitato a due. +@xref{Sequenze di protezione}. + +@item +@code{print} e @code{printf} non terminano il programma dopo alcuni +errori di output. +@xref{Continuazione dopo errori}. + +@item +Per molti anni, lo standard POSIX richiedeva che la separazione dei campi +di un record fosse fatta per default +quando si incontrano spazi e TAB, e questo @`e il comportamento di +@command{gawk} se si specifica l'opzione @option{--posix}. Dal 2013 +il comportamento originario @`e stato ripristinato, e ora +il default per separare i campi con l'opzione @option{--posix} ammette +anche il ritorno a capo come separatore di campi. + +@item +Il supporto per MirBSD @`e stato rimosso. + +@item +Il supporto per GNU/Linux sull'architettura Alpha @`e stato rimosso. +@end itemize + +@c XXX ADD MORE STUFF HERE +@end ifclear + +@node Estensioni comuni +@appendixsec Sommario Estensioni Comuni + +@cindex estensioni, Brian Kernighan @command{awk} +@cindex estensioni, @command{mawk} +La tabella seguente dettaglia le estensioni comuni supportate +da @command{gawk}, da Brian Kernighan @command{awk} e da @command{mawk}, +le tre versioni liberamente disponibili pi@`u usate di @command{awk} +(@pxref{Altre versioni}). + +@multitable {File speciale @file{/dev/stderr}} {BWK @command{awk} } {@command{mawk}} {@command{gawk}} {Standard attuale} +@headitem Funzionalit@`a @tab BWK @command{awk} @tab @command{mawk} @tab @command{gawk} @tab Standard attuale +@item Sequenza di protezione @samp{\x} @tab X @tab X @tab X @tab +@item Stringa nulla come @code{FS} @tab X @tab X @tab X @tab +@item File speciale @file{/dev/stdin} @tab X @tab X @tab X @tab +@item File speciale @file{/dev/stdout} @tab X @tab X @tab X @tab +@item File speciale @file{/dev/stderr} @tab X @tab X @tab X @tab +@item @code{delete} senza indici @tab X @tab X @tab X @tab X +@item Funzione @code{fflush()} @tab X @tab X @tab X @tab X +@item @code{length()} di un vettore @tab X @tab X @tab X @tab +@item Istruzione @code{nextfile} @tab X @tab X @tab X @tab X +@item Operatori @code{**} e @code{**=} @tab X @tab @tab X @tab +@item Parola chiave @code{func} @tab X @tab @tab X @tab +@item Variabile @code{BINMODE} @tab @tab X @tab X @tab +@item @code{RS} come @dfn{regexp} @tab @tab X @tab X @tab +@item Funzioni gestione data/ora @tab @tab X @tab X @tab +@end multitable + +@node Intervalli e localizzazione +@appendixsec Intervalli @dfn{regexp} e localizzazione: una lunga e triste storia + +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} descrive la storia confusionaria degli intervalli +all'interno di espressioni regolari, le loro relazioni con la localizzazione, +e l'effetto da ci@`o determinato su diverse versioni di @command{gawk}. + +Gli strumenti originali Unix aventi a che fare con espressioni regolari +stabilivano che intervalli di caratteri (come @samp{[a-z]}) individuavano +un carattere qualsiasi tra il primo carattere dell'intervallo e l'ultimo +carattere dello stesso, entrambi inclusi. L'ordinamento era basato sul +valore numerico di ogni carattere come era rappresentato all'interno +del computer, nell'insieme di caratteri proprio di ogni macchina. +Quindi, su sistemi che adottano la codifica ASCII, @samp{[a-z]} individua +tutte le lettere minuscole, e solo +quelle, in quanto i valori numerici che rappresentano le lettere dalla +@samp{a} fino alla @samp{z} sono contigui. (In un sistema che adotta la +codifica EBCDIC, l'intervallo @samp{[a-z]} comprende anche ulteriori +caratteri non alfabetici.) + +Quasi tutti i testi di introduzione allo Unix spiegavano che le espressioni +di intervallo funzionavano in questo modo, e in particolare insegnavano che +la maniera ``corretta'' per individuare le lettere minuscole era con +@samp{[a-z]} e che @samp{[A-Z]} era il modo ``corretto'' per individuare le +lettere maiuscole. +E, in effetti, era proprio cos@`{@dotless{i}}.@footnote{E la vita era semplice.} + +Lo standard POSIX 1992 introduceva l'idea di localizzazione +(@pxref{Localizzazioni}). +Poich@'e molte localizzazioni comprendono altre lettere, oltre alle 26 +lettere dell'alfabeto inglese, lo standard POSIX introduceva le classi +di carattere (@pxref{Espressioni tra parentesi quadre}) per permettere +l'individuazione di differenti insiemi di caratteri, in aggiunta a quelli +tradizionali presenti nell'insieme di caratteri ASCII. + +Tuttavia, lo standard @emph{ha modificato} l'interpretazione delle +espressioni di intervallo. +Nelle localizzazioni @code{"C"} e @code{"POSIX"}, +un'espressione di intervallo come +@samp{[a-dx-z]} @`e ancora equivalente a @samp{[abcdxyz]}, secondo l'ordine +della codifica ASCII. +Ma in tutte le altre localizzazioni l'ordinamento @`e basato su quel che +si chiama @dfn{ordine di collazione}. + +Cosa vuol dire? +In molte localizzazioni, le lettere @samp{A} e @samp{a} vengono entrambe +prima di @samp{B}. +In altre parole, queste localizzazioni ordinano i caratteri nel modo in cui +sono ordinati in un dizionario, +e @samp{[a-dx-z]} non @`e detto che equivalga a @samp{[abcdxyz]}; +invece, potrebbe essere equivalente a @samp{[ABCXYabcdxyz]}, per fare un +esempio. + +Su questo punto @`e opportuno insistere: molta documentazione afferma che +si dovrebbe usare @samp{[a-z]} per identificare un carattere minuscolo. +Ma su sistemi con localizzazioni +non-ASCII, un tale intervallo potrebbe includere tutti i caratteri maiuscoli +tranne @samp{A} o @samp{Z}! Questo ha continuato a essere una fonte di +equivoci perfino nel ventunesimo secolo. + +Per dare un'idea del tipo di problemi, l'esempio seguente usa la funzione +@code{sub()}, che effettua una sostituzione di testo all'interno di una +stringa (@pxref{Funzioni per stringhe}). Qui, l'idea @`e quella di rimuovere +i caratteri maiuscoli a fine stringa: + +@example +$ @kbd{echo qualcosa1234abc | gawk-3.1.8 '@{ sub("[A-Z]*$", ""); print @}'} +@print{} qualcosa1234a +@end example + +@noindent +Questo non @`e l'output che ci si aspettava, perch@'e, il @samp{bc} alla fine di +@samp{qualcosa1234abc} non dovrebbe essere individuato da @samp{[A-Z]*}. +Un tale risultato dipende dalle impostazioni di localizzazione (e quindi +potrebbe non succedere sul sistema che si sta usando). + +@cindex Unicode +Considerazioni simili valgono per altri intervalli. Per esempio, @samp{["-/]} +@`e perfettamente valido in ASCII, ma non @`e valido in molte localizzazioni +Unicode, p.es. in @code{en_US.UTF-8}. + +Il codice delle prime versioni di @command{gawk} per individuare le +@dfn{regexp} non teneva conto della localizzazione, e quindi gli +intervalli potevano essere interpretati in maniera tradizionale. + +Quando @command{gawk} ha iniziato a usare metodi di ricerca di @dfn{regexp} +che tengono conto della localizzazione, sono iniziati i problemi; +a maggior ragione in quanto sia GNU/Linux che i venditori di versioni +commerciali di Unix +avevano iniziato a implementare localizzazioni non-ASCII, +@emph{adottandole per default}. La domanda che forse si udiva pi@`u spesso +era del tipo: ``Perch@'e @samp{[A-Z]} individua lettere minuscole?!?'' + +@cindex Berry, Karl +Questa situazione @`e in essere da circa 10 anni, se non di pi@`u, e +il manutentore di @command{gawk} si @`e stufato di continuare a spiegare che +@command{gawk} stava semplicemente implementando quelli che sono gli +standard, e che il problema stava nella localizzazione dell'utente. Nella +fase di sviluppo della @value{PVERSION} 4.0, @command{gawk} @`e stato modificato +in modo da trattare sempre gli +intervalli "come si faceva prima di POSIX", a meno che non si specifichi +l'opzione @option{--posix} (@pxref{Opzioni}).@footnote{Ed +@`e cos@`{@dotless{i}} che @`e nata la Campagna per l'Interpretazione Razionale degli +Intervalli (in inglese, RRI [@dfn{Rational Range Interpretation}]). +Un certo +numero di strumenti GNU hanno gi@`a implementato questa modifica, o +lo faranno presto. Grazie a Karl Berry per aver coniato la frase +``Rational Range Interpretation''.} + +Fortunatamente, un po' prima del rilascio definitivo della versione 4.0 di +@command{gawk}, il manutentore ha appreso che lo standard 2008 aveva +modificato la definizione di intervallo, e che, al di fuori delle +localizzazioni @code{"C"} e @code{"POSIX"}, il significato di espressione +di intervallo era ora +@emph{indefinito}.@footnote{Si veda +@uref{http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03_05, lo standard} +e +@uref{http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap09.html#tag_21_09_03_05, le motivazioni}.} + +Adottando questo simpatico termine tecnico, lo standard permette agli +implementatori di implementare gli intervalli nella maniera che preferiscono. +Il manutentore di @command{gawk} ha deciso di implementare la regola pre-POSIX +sia per l'individuazione di default delle @dfn{regexp} sia quando si +specificano le opzioni @option{--traditional} o @option{--posix}. +In ogni caso @command{gawk} aderisce allo standard POSIX. + +@node Contributori +@appendixsec I principali contributori a @command{gawk} +@cindex @command{gawk}, lista di contributori a +@quotation +@i{Riconoscere sempre il merito, se un merito va riconosciuto.} +@author Anonimo +@end quotation + +Questa @value{SECTION} elenca le persone che hanno maggiormente contribuito +allo sviluppo di @command{gawk} e/o alla stesura di questo @value{DOCUMENT}, +in ordine approssimativamente cronologico: + +@itemize @value{BULLET} +@item +@cindex Aho, Alfred +@cindex Weinberger, Peter +@cindex Kernighan, Brian +Il Dr.@: Alfred V.@: Aho, +il Dr.@: Peter J.@: Weinberger, e +il Dr.@: Brian W.@: Kernighan, tutti dei Bell Laboratories, +hanno progettato e implementato @command{awk} per Unix, +da cui @command{gawk} trae la maggioranza delle sue funzionalit@`a. + +@item +@cindex Rubin, Paul +Paul Rubin, +autore del progetto e dell'implementazione iniziale del 1986, ha +scritto la prima bozza (di circa 40 pagine) di questo @value{DOCUMENT}. + +@item +@cindex Fenlason, Jay +Jay Fenlason +ha completato l'implementazione iniziale. + +@item +@cindex Close, Diane +Diane Close +ha rivisto la prima bozza di questo @value{DOCUMENT}, portandolo alla +lunghezza di circa 90 pagine. + +@item +@cindex Stallman, Richard +Richard Stallman +ha aiutato a completare l'implementazione e la bozza iniziale di questo +@value{DOCUMENT}. +@`E anche il fondatore della FSF e del progetto GNU. + +@item +@cindex Woods, John +John Woods +ha scritto porzioni di codice (volti principalmente alla correzione di +errori) nella versione iniziale di @command{gawk}. + +@item +@cindex Trueman, David +Nel 1988, +David Trueman +si @`e fatto carico della manutenzione principale di @command{gawk}, +rendendolo compatibile col ``nuovo'' @command{awk} e +migliorandone parecchio la velocit@`a di esecuzione. + +@item +@cindex Kwok, Conrad +@cindex Garfinkle, Scott +@cindex Williams, Kent +Conrad Kwok, +Scott Garfinkle +e +Kent Williams +hanno per primi portato il programma all'ambiente MS-DOS, usando varie +versioni del compilatore MSC. + +@item +@cindex Rankin, Pat +Pat Rankin +ha portato il programma all'ambiente VMS, preparando anche la relativa +documentazione. + +@item +@cindex Peterson, Hal +Hal Peterson +@`e stato di aiuto nel portare @command{gawk} nei sistemy Cray. +(L'ambiente Cray non @`e pi@`u supportato.) + +@item +@cindex Rommel, Kai Uwe +Kai Uwe Rommel +ha portato per primo il programma all'ambiente OS/2, preparando anche +la relativa documentazione. + +@item +@cindex Jaegermann, Michal +Michal Jaegermann +ha portato il programma all'ambiente Atari, preparando anche la relativa +documentazione. +(L'ambiente Atari non @`e pi@`u supportato.) +Michal continua a effettuare controlli di portabilit@`a, +e ha molto contribuito a consentire a @command{gawk} +di funzionare su sistemi diversi da quelli a 32 bit. + +@item +@cindex Fish, Fred +Fred Fish +ha portato il programma all'ambiente Amiga, preparando anche la relativa +documentazione. +(Purtroppo Fred non @`e pi@`u tra noi, e questo ambiente non @`e pi@`u supportato.) + +@item +@cindex Deifik, Scott +Scott Deifik +si @`e occupato della manutenzione per MS-DOS usando il compilatore DJGPP. + +@item +@cindex Zaretskii, Eli +Eli Zaretskii +si occupa della manutenzione della versione per MS-Windows, nell'ambiente +MinGW. + +@item +@cindex Grigera, Juan +Juan Grigera +@`e autore di una versione di @command{gawk} per sistemi Windows32. +(Questa versione non @`e pi@`u supportata.) + +@item +@cindex Hankerson, Darrel +Per molti anni, il +Dr.@: Darrel Hankerson +ha fatto da coordinatore per le varie versioni che giravano su diverse +piattaforme PC e ha creato distribuzioni binarie per vari sistemi operativi +che girano sui PC. +Il suo aiuto @`e stato importante per mantenere aggiornata la documentazione +per le diverse piattaforme PC. + +@item +@cindex Zoulas, Christos +Christos Zoulas +ha scritto la funzione predefinita @code{extension()} per aggiungere +dinamicamente nuove funzioni. +(Questa funzionalit@`a @`e divenuta obsoleta a partire da @command{gawk} 4.1.) + +@item +@cindex Kahrs, J@"urgen +J@"urgen Kahrs +ha scritto la prima versione del codice per interagire con la rete +TCP/IP, con la relativa documentazione, e fornito le ragioni per l'aggiunta +dell'operatore @samp{|&}. + +@item +@cindex Davies, Stephen +Stephen Davies +ha portato per la prima volta il programma all'ambiente Tandem, preparando +anche la relativa documentazione. +(Tuttavia, questa versione non @`e pi@`u supportata.) +Stephen @`e anche stato determinante nel lavoro iniziale per integrare il codice +interno di gestione dei byte nel +complesso del codice di @command{gawk}. + +@item +@cindex Woehlke, Matthew +Matthew Woehlke +ha migliorato l'aderenza allo standard POSIX nei sistemi Tandem che +implementano lo standard. + +@item +@cindex Brown, Martin +Martin Brown +ha portato il programma all'ambiente BeOS, preparando anche la relativa +documentazione. +(L'ambiente BeOS non @`e pi@`u supportato.) + +@item +@cindex Peters, Arno +Arno Peters +ha fatto il lavoro iniziale necessario per consentire alla configurazione +di @command{gawk} di usare GNU Automake e GNU @command{gettext}. + +@item +@cindex Broder, Alan J.@: +Alan J.@: Broder +ha scritto la prima versione della funzione @code{asort()} e anche +il codice per gestire il terzo argomento opzionale della funzione +@code{match()}. + +@item +@cindex Buening, Andreas +Andreas Buening +ha aggiornato la versione di @command{gawk} per OS/2. + +@item +@cindex Hasegawa, Isamu +Isamu Hasegawa, +dell'IBM in Giappone, ha contribuito con il supporto per i caratteri multibyte. + +@item +@cindex Benzinger, Michael +Michael Benzinger ha sviluppato il codice iniziale per l'istruzione +@code{switch}. + +@item +@cindex McPhee, Patrick +Patrick T.J.@: McPhee ha sviluppato il codice per il caricamento +dinamico negli ambienti Windows32. +(Questa funzionalit@`a non @`e pi@`u supportata.) + +@item +@cindex Wallin, Anders +Anders Wallin ha aiutato a continuare il supporto della versione VMS +di @command{gawk} per parecchi anni. + +@item +@cindex Gordon, Assaf +Assaf Gordon ha scritto il codice per implementare +l'opzione @option{--sandbox}. + +@item +@cindex Haque, John +John Haque @`e autore dei seguenti contributi: + +@itemize @value{MINUS} +@item +Le modifiche per convertire @command{gawk} +in un interprete di codice a livello di byte, compreso il debugger + +@item +L'aggiunta di veri vettori di vettori + +@item +Le modifiche ulteriori per il supporto del calcolo a precisione +arbitraria + +@item +Il testo iniziale di +@ref{Calcolo con precisione arbitraria} + +@item +Il lavoro per unificare le tre varianti del programma @command{gawk}, +in vista della versione 4.1 + +@item +I miglioramenti alla gestione interna dei vettori per i vettori i cui +indici sono dei numeri interi + +@item +A John, insieme a Pat Rankin, si devono i miglioramenti alla funzionalit@`a +di ordinamento dei vettori. +@end itemize + +@cindex Papadopoulos, Panos +@item +Panos Papadopoulos ha scritto il testo originale per +@ref{Includere file}. + +@item +@cindex Yawitz, Efraim +Efraim Yawitz ha scritto il testo originale per il @ref{Debugger}. + +@item +@cindex Schorr, Andrew +Lo sviluppo dell'estensione API rilasciata per la prima volta con +@command{gawk} 4.1 @`e stata principalmente guidata da +Arnold Robbins e Andrew Schorr, con notevoli contributi dal +resto del team di sviluppo. + +@cindex Malmberg, John E. +@item +John Malmberg ha apportato miglioramenti significativi alla versione +OpenVMS e alla relativa documentazione. + +@item +@cindex Colombo, Antonio +Antonio Giovanni Colombo ha riscritto diversi esempi, che non erano pi@`u +attuali, contenuti nei primi capitoli, e gliene sono estremamente grato. + +@item +@cindex Robbins, Arnold +Arnold Robbins +ha lavorato su @command{gawk} dal 1988, dapprima +aiutando David Trueman e in seguito, dal 1994 circa, come +manutentore principale. +@end itemize + +@node Sommario della storia +@appendixsec Sommario + +@itemize @value{BULLET} +@item +Il linguaggio @command{awk} si @`e evoluto col passare degli anni. La prima +versione risale a Unix V7, circa 1978. Nel 1987, per la versione Unix +System V Release 3.1, sono state fatte al linguaggio delle modifiche +importanti, inclusa la possibilit@`a di avere funzioni definite dall'utente. +Ulteriori modifiche sono state fatte per la versione System V Release 4, nel +1989. +Dopo di allora, sono state apportate ulteriori modifiche minori, +per implementare lo standard POSIX. + +@item +L'@command{awk} di Brian Kernighan prevede un piccolo numero di estensioni +implementate di comune accordo con altre versioni di @command{awk}. + +@item +@command{gawk} prevede un elevato numero di estensioni rispetto +a POSIX @command{awk}. +Queste estensioni possono essere disabilitate specificando l'opzione +@option{--traditional} o @option{--posix}. + +@item +L'interazione tra localizzazioni POSIX e individuazione di @dfn{regexp} +in @command{gawk} @`e stata causa di malintesi nel corso degli anni. Oggi +@command{gawk} implementa l'Interpretazione Razionale degli Intervalli +(@dfn{Rational Range Interpretation}), dove +intervalli nella forma @samp{[a-z]} individuano @emph{solo} i caratteri +numericamente compresi tra +@samp{a} e @samp{z} nella rappresentazione nativa dei caratteri in quella +particolare macchina. Normalmente quella in uso @`e quella ASCII, +ma pu@`o essere EBCDIC sui sistemi IBM S/390. + +@item +Molte persone hanno contribuito allo sviluppo di @command{gawk} nel corso +degli anni. Spero che l'elenco fornito in questo @value{CHAPTER} sia +esauriente e attribuisca il giusto riconoscimento quando questo @`e dovuto. + +@end itemize + +@node Installazione +@appendix Installare @command{gawk} + +@c last two commas are part of see also +@cindex sistemi operativi, si veda anche GNU/Linux@comma{} sistemi operativi per PC@comma{} Unix +@cindex @command{gawk}, installare +@cindex installare @command{gawk} +Quest'appendice contiene istruzioni per installare @command{gawk} sulle +varie piattaforme supportate dagli sviluppatori. Lo sviluppatore +principale supporta GNU/Linux (e Unix), mentre le altre piattaforme sono +sono curate da altri sviluppatori. +@xref{Bug} +per gli indirizzi di posta elettronica di chi effettua la manutenzione +della versione specifica di una particolare piattaforma. + +@menu +* Distribuzione di Gawk:: Contenuto della distribuzione di @command{gawk}. +* Installazione Unix:: Installare @command{gawk} su varie versioni + di Unix. +* Installazione non-Unix:: Installazioni su altri Sistemi Operativi. +* Bug:: Notificare problemi e bug. +* Altre versioni:: Altre implementazioni di @command{awk} + liberamente disponibili. +* Sommario dell'installazione:: Sommario dell'installazione. +@end menu + +@node Distribuzione di Gawk +@appendixsec La distribuzione di @command{gawk} +@cindex codice sorgente di @command{gawk} +@cindex sorgente, codice, @command{gawk} + +Questa @value{SECTION} spiega come ottenere la distribuzione +di @command{gawk}, come scompattarla, e cosa @`e contenuto nei vari file +e nelle sottodirectory risultanti. + +@menu +* Scaricare:: Come ottenere la distribuzione. +* Scompattazione:: Come estrarre la distribuzione. +* Contenuti della distribuzione:: Cosa c'@`e nella distribuzione. +@end menu + +@node Scaricare +@appendixsubsec Ottenere la distribuzione di @command{gawk} +@cindex @command{gawk}, codice sorgente@comma{} ottenere il +@cindex codice sorgente di @command{gawk}, ottenere il +Ci sono due modi per ottenere del software GNU: + +@itemize @value{BULLET} +@item +Copiarlo da qualcuno che ce l'abbia gi@`a. + +@cindex FSF (Free Software Foundation) +@cindex Free Software Foundation (FSF) +@item +Ottenere @command{gawk} +dal sito Internet +@code{ftp.gnu.org}, nella directory @file{/gnu/gawk}. +@`E possibile accedere al sito sia via @command{ftp} anonimo che via @code{http}. +Se si dispone del programma @command{wget}, si pu@`o utilizzarlo digitando un +comando simile a questo: + +@example +wget http://ftp.gnu.org/gnu/gawk/gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz +@end example +@end itemize + +L'archivio che contiene il software GNU @`e disponibile in vari cloni +(@dfn{mirror}) in tutto il mondo. +La lista aggiornata dei siti clone @`e disponibile nel +@uref{http://www.gnu.org/order/ftp.html, sito web principale della FSF}. +Si tenti di usare uno dei siti-clone; dovrebbero essere meno trafficati, ed @`e +possibile che ce ne sia uno pi@`u vicino. + +Si pu@`o anche scaricare la distribuzione del sorgente di @command{gawk} +dal deposito Git ufficiale; per maggiori informazioni, si veda +@ref{Accedere ai sorgenti}. + +@node Scompattazione +@appendixsubsec Scompattare la distribuzione +@command{gawk} @`e distribuito sotto forma di parecchi file @code{tar} +compressi con differenti programmi di compressione: @command{gzip}, +@command{bzip2} +e @command{xz}. Per amor di semplicit@`a, il resto di queste istruzioni +presuppone che si stia usando quella compressa col programma GNU Gzip +(@command{gzip}). + +Una volta che si ha a disposizione la distribuzione (p.es., +@file{gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz}), +va usato @code{gzip} per scompattare il file e quindi @code{tar} per estrarne i +file. Si pu@`o usare la seguente @dfn{pipe} per produrre la distribuzione +@command{gawk}: + +@example +gzip -d -c gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz | tar -xvpf - +@end example + +In un sistema che abbia la versione GNU di @command{tar}, si +pu@`o far effettuare la scompattazione direttamente a @command{tar}: + +@example +tar -xvpzf gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz +@end example + +@noindent +L'estrazione dei file dall'archivio +crea una directory di nome @file{gawk-@value{VERSION}.@value{PATCHLEVEL}} +nella directory corrente. + +Il @value{FN} della distribuzione @`e nella forma +@file{gawk-@var{V}.@var{R}.@var{P}.tar.gz}. +La @var{V} rappresenta la versione maggiore di @command{gawk}, +la @var{R} rappresenta il rilascio corrente della versione @var{V}, e +la @var{P} rappresenta un @dfn{patch level}, che sta a indicare che +correzioni a errori minori sono state incluse nel rilascio. +Il @dfn{patch level} corrente @`e @value{PATCHLEVEL}, ma quando ci si procura +una distribuzione, andr@`a ottenuta quella con il livello pi@`u alto di +versione, rilascio e @dfn{patch}. +(Si noti, comunque, che livelli di @dfn{patch} maggiori o uguali a 70 +denotano versioni ``beta'', ossia versioni non destinate a essere usate +in produzione; non si dovrebbero utilizzare tali versioni, se non si @`e +disposti a sperimentare.) +Se non si sta usando un sistema Unix o GNU/Linux, i modi per ottenere +e scompattare la distribuzione di @command{gawk} sono differenti. +Si dovrebbe sentire un esperto di quel sistema. + +@node Contenuti della distribuzione +@appendixsubsec Contenuti della distribuzione @command{gawk} +@cindex @command{gawk}, distribuzione di +@cindex distribuzione di @command{gawk} + +La distribuzione di @command{gawk} contiene un certo numero di file +sorgente in C, di file di documentazione, di sottodirectory, e di file +utilizzati durante il processo di configurazione +(@pxref{Installazione Unix}), +come pure parecchie sottodirectory relative a diversi sistemi operativi +non-Unix: + +@table @asis +@item Vari file @samp{.c}, @samp{.y} e @samp{.h} +Questi file contengono il codice sorgente vero e proprio di @command{gawk}. +@end table + +@table @file +@item support/* +Intestazioni C e file sorgente per routine che @command{gawk} +usa, ma che non sono parte della sua funzionalit@`a +fondamentale. Per esempio, analisi di argomenti, controlli +di corrispondenze di espressioni regolari, e routine per +generare numeri casuali sono tutti mantenuti qui. + +@item ABOUT-NLS +Un file contenente informazioni sul comando GNU @command{gettext} e +sulle traduzioni. + +@item AUTHORS +Un file con alcune informazioni su chi ha scritto @command{gawk}. +Esiste solo per placare i pedanti della Free Software Foundation. + +@item README +@itemx README_d/README.* +File descrittivi: vari @file{README} ("leggimi") per @command{gawk} sotto Unix e per +tutte le varie altre combinazioni hardware e software. + +@item INSTALL +Un file che fornisce una panoramica sul processo di configurazione e installazione. + +@item ChangeLog +Una lista dettagliata delle modifiche apportate al codice sorgente, +ai problemi risolti e ai miglioramenti introdotti. + +@item ChangeLog.0 +Una lista meno recente di modifiche al codice sorgente. + +@item NEWS +Una lista di modifiche a @command{gawk} a partire dall'ultimo rilascio +o @dfn{patch}. + +@item NEWS.0 +Una lista meno recente di modifiche a @command{gawk}. + +@item COPYING +La @dfn{GNU General Public License}. + +@item POSIX.STD +Una descrizione di comportamenti nello standard POSIX per @command{awk} che +sono lasciati indefiniti, o ai quali @command{gawk} non pu@`o conformarsi +pienamente, come pure una lista di specifiche che lo standard POSIX dovrebbe +contenere, ma che non sono presenti. + +@cindex intelligenza artificiale, @command{gawk} e +@cindex @command{gawk} e l'intelligenza artificiale +@item doc/awkforai.txt +Puntatori alla bozza originale di un breve articolo +che spiega perch@'e @command{gawk} @`e un linguaggio adatto alla +programmazione nel campo dell'intelligenza artificiale (AI). + +@item doc/bc_notes +Una breve descrizione della struttura interna a livello di byte di +@command{gawk} [``byte code'']. + +@item doc/README.card +@itemx doc/ad.block +@itemx doc/awkcard.in +@itemx doc/cardfonts +@itemx doc/colors +@itemx doc/macros +@itemx doc/no.colors +@itemx doc/setter.outline +Il sorgente @command{troff} per una scheda di riferimento a cinque colori +di @command{awk}. +Per ottenere la versione a colori @`e richiesta una versione recente di +@command{troff}, come la versione GNU di @command{troff} (@command{groff}). +Si veda il file @file{README.card} per istruzioni su come comportarsi se @`e +disponibile solo una versione pi@`u vecchia di @command{troff}. + +@item doc/gawk.1 +Il sorgente @command{troff} di una pagina di manuale [@dfn{man}] +che descrive @command{gawk}. +Questa pagina @`e distribuita a beneficio degli utenti Unix. + +@cindex Texinfo +@item doc/gawktexi.in +@itemx doc/sidebar.awk +Il file sorgente Texinfo di questo @value{DOCUMENT}. +Dovrebbe venire elaborato da @file{doc/sidebar.awk} +prima di essere elaborato con @command{texi2dvi} o @command{texi2pdf} +per produrre un documento stampato, o +con @command{makeinfo} per produrre un file Info o HTML. +Il @file{Makefile} si occupa di questa elaborazione e produce +la versione stampabile tramite i comandi +@command{texi2dvi} o @command{texi2pdf}. + +@item doc/gawk.texi +Il file prodotto elaborando @file{gawktexi.in} +tramite @file{sidebar.awk}. + +@item doc/gawk.info +Il file Info generato per questo @value{DOCUMENT}. + +@item doc/gawkinet.texi +Il file sorgente Texinfo per +@ifinfo +@inforef{Top, , Introduzione generale, gawkinet, @value{GAWKINETTITLE}}. +@end ifinfo +@ifnotinfo +@cite{@value{GAWKINETTITLE}}. +@end ifnotinfo +Dovrebbe venire elaborato con @TeX{} +(tramite @command{texi2dvi} o @command{texi2pdf}) +per produrre un documento stampato o +con @command{makeinfo} per produrre un file Info o HTML. + +@item doc/gawkinet.info +Il file Info generato per +@cite{@value{GAWKINETTITLE}}. + +@item doc/igawk.1 +Il sorgente @command{troff} per una pagina di manuale relativa al +programma @command{igawk} descritto +@ifnottex +in +@end ifnottex +@iftex +nella +@end iftex +@ref{Programma igawk}. +(Poich@'e @command{gawk} prevede ora internamente l'uso della direttiva +@code{@@include}, +n@'e @command{igawk} n@'e @file{igawk.1} sono effettivamente installati.) + +@item doc/Makefile.in +Il file in input usato durante la procedura di configurazione per +generare l'effettivo @file{Makefile} da usare per creare la documentazione. + +@item Makefile.am +@itemx */Makefile.am +File usati dal software GNU Automake per generare +il file @file{Makefile.in} usato da Autoconf e dallo script +@command{configure}. + +@item Makefile.in +@itemx aclocal.m4 +@itemx bisonfix.awk +@itemx config.guess +@itemx configh.in +@itemx configure.ac +@itemx configure +@itemx custom.h +@itemx depcomp +@itemx install-sh +@itemx missing_d/* +@itemx mkinstalldirs +@itemx m4/* +Questi file e sottodirectory sono usati per configurare e compilare +@command{gawk} per vari sistemi Unix. L'uso di molti tra questi file @`e spiegato +@iftex +nella +@end iftex +@ifnottex +in +@end ifnottex +@ref{Installazione Unix}. I rimanenti hanno una funzione di supporto +per l'infrastruttura. + +@item po/* +La directory @file{po} contiene la traduzione in varie lingue +dei messaggi emessi da @command{gawk}. + +@item awklib/extract.awk +@itemx awklib/Makefile.am +@itemx awklib/Makefile.in +@itemx awklib/eg/* +La directory @file{awklib} contiene una copia di @file{extract.awk} +(@pxref{Programma extract}), +che pu@`o essere usato per estrarre i programmi di esempio dal file sorgente +Texinfo di questo @value{DOCUMENT}. Contiene anche un file +@file{Makefile.in}, che +@command{configure} usa per generare un @file{Makefile}. +@file{Makefile.am} @`e usato da GNU Automake per creare @file{Makefile.in}. +Le funzioni di libreria descritte +@iftex +nel +@end iftex +@ifnottex +in +@end ifnottex +@ref{Funzioni di libreria}, +sono incluse come file pronti per l'uso nella distribuzione @command{gawk}. +Essi sono installati come parte della procedura di installazione. +I rimanenti programmi contenuti in questo @value{DOCUMENT} sono disponibili +nelle appropriate sottodirectory di @file{awklib/eg}. + +@item extension/* +Il codice sorgente, le pagine di manuale, e i file di infrastruttura per +gli esempi di estensione incluse con @command{gawk}. +@xref{Estensioni dinamiche}, per ulteriori dettagli. + +@item extras/* +Ulteriori file, non-essenziali. Al momento, questa directory contiene +alcuni file da eseguire al momento di iniziare una sessione, +da installare nella directory @file{/etc/profile.d} +per essere di aiuto nella gestione delle variabili di ambiente +@env{AWKPATH} e @env{AWKLIBPATH}. +@xref{File da usare a inizio sessione}, per ulteriori informazioni. + +@item posix/* +File necessari per compilare @command{gawk} su sistemi conformi allo +standard POSIX. + +@item pc/* +File necessari per compilare @command{gawk} sotto MS-Windows +(@pxref{Installazione su PC} per i dettagli). + +@item vms/* +File necessari per compilare @command{gawk} sotto Vax/VMS e OpenVMS +(@pxref{Installazione su VMS} per i dettagli). + +@item test/* +Una serie di test per +@command{gawk}. Si pu@`o usare @samp{make check} dalla directory principale +di @command{gawk} per provare se la serie di test funziona con la +versione in uso di @command{gawk}. +Se @command{gawk} supera senza errori @samp{make check}, si pu@`o essere +sicuri che sia stato installato e configurato correttamente su un dato +sistema. +@end table + +@node Installazione Unix +@appendixsec Compilare e installare @command{gawk} su sistemi di tipo Unix + +Normalmente, si pu@`o compilare e installare @command{gawk} immettendo +solo un paio di comandi. Comunque, se si ci si trova in un sistema +insolito, pu@`o essere necessario +dover configurare @command{gawk} per quel dato sistema. + +@menu +* Installazione veloce:: Compilare @command{gawk} sotto Unix. +* File da usare a inizio sessione:: Funzioni di personalizzazione della + shell. +* Ulteriori opzioni di configurazione:: Altre opzioni utilizzabili in fase di + compilazione. +* Filosofia della configurazione:: Come si suppone che tutto funzioni. +@end menu + +@node Installazione veloce +@appendixsubsec Compilare @command{gawk} per sistemi di tipo Unix + +Questi normali passi di installazione dovrebbero essere sufficienti in +tutti i moderni sistemi in commercio derivati da Unix, ossia +GNU/Linux, sistemi basati su BSD, e l'ambiente Cygwin sotto MS-Windows. + +Dopo aver estratto la distribuzione di @command{gawk}, posizionarsi con +@command{cd} nella directory +@file{gawk-@value{VERSION}.@value{PATCHLEVEL}}. Come per la maggior parte dei +programmi GNU, occorre configurare @command{gawk} per il sistema in uso, +eseguendo il programma @command{configure}. Questo programma @`e +uno script della shell Bourne, che @`e stato generato automaticamente +usando il comando GNU Autoconf. +@ifnotinfo +(Il software Autoconf @`e +descritto in dettaglio in +@cite{Autoconf---Generating Automatic Configuration Scripts}, +che pu@`o essere trovato in rete sul sito +@uref{http://www.gnu.org/software/autoconf/manual/index.html, +della Free Software Foundation}.) +@end ifnotinfo +@ifinfo +(Il software Autoconf @`e descritto in dettaglio a partire da +@inforef{Top, , Autoconf, autoconf,Autoconf---Generating Automatic Configuration Scripts}.) +@end ifinfo + +Per configurare @command{gawk} basta eseguire @command{configure}: + +@example +sh ./configure +@end example + +Questo produce i file @file{Makefile} e @file{config.h} adatti al sistema +in uso. +Il file @file{config.h} descrive varie situazioni relative al sistema in uso. +@`E possibile modificare il @file{Makefile} per +cambiare la variabile @code{CFLAGS}, che controlla +le opzioni di riga di comando da passare al compilatore C (come i livelli +di ottimizzazione o la richiesta di generare informazioni per il @dfn{debug}). + +In alternativa, si possono specificare dei valori a piacere per +molte delle variabili di @command{make} sulla riga di comando, +come @code{CC} e @code{CFLAGS}, quando + si chiama il programma +@command{configure}: + +@example +CC=cc CFLAGS=-g sh ./configure +@end example + +@noindent +Si veda il file @file{INSTALL} nella distribuzione di @command{gawk} per +tutti i dettagli. + +Dopo aver eseguito @command{configure} ed eventualmente modificato +@file{Makefile}, +va dato il comando: + +@example +make +@end example + +@noindent +Poco dopo, si dovrebbe avere a disposizione una versione eseguibile +di @command{gawk}. +Questo @`e tutto! +Per verificare se @command{gawk} funziona correttamente, +va dato il comando @samp{make check}. Tutti i test dovrebbero terminare con +successo. +Se questi passi non producono il risultato desiderato, o se qualche +test fallisce, controllare i file nella directory @file{README_d} +per determinare se quello che @`e capitato @`e un problema noto. +Se il problema capitato non @`e descritto l@`{@dotless{i}}, +inviare una segnalazione di @dfn{bug} (@pxref{Bug}). + +Naturalmente, dopo aver compilato @command{gawk}, verosimilmente +andr@`a installato. Per fare ci@`o, occorre eseguire il comando +@samp{make install}, disponendo delle autorizzazioni necessarie. +Come acquisirle varia da sistema a sistema, ma su molti sistemi si pu@`o +usare il comando @command{sudo} per ottenerle. Il comando da immettere +diventa in questo caso @samp{sudo make install}. @`E probabile che sia +necessario fornire una password, ed essere stati messi nella lista degli +utenti che possono utilizzare il comando @command{sudo}. + +@node File da usare a inizio sessione +@appendixsubsec File di inizializzazione della shell + +La distribuzione contiene i file da usare a inizio sessione +@file{gawk.sh} e +@file{gawk.csh}, che contengono funzioni che possono essere di aiuto +nel gestire le variabili di ambiente +@env{AWKPATH} e @env{AWKLIBPATH}. +Su un sistema Fedora GNU/Linux, questi file dovrebbero essere installati +nella directory @file{/etc/profile.d}; +su altre piattaforme, la posizione corretta pu@`o essere differente. + +@table @command + +@cindex @command{gawkpath_default}, funzione della shell +@cindex funzione della shell @command{gawkpath_default} +@item gawkpath_default +Ripristina la variabile d'ambiente @env{AWKPATH} al suo valore di default. + +@cindex @command{gawkpath_prepend}, funzione della shell +@cindex funzione della shell @command{gawkpath_prepend} +@item gawkpath_prepend +Aggiunge l'argomento all'inizio della variabile d'ambiente @env{AWKPATH}. + +@cindex @command{gawkpath_append}, funzione della shell +@cindex funzione della shell @command{gawkpath_append} +@item gawkpath_append +Aggiunge l'argomento alla fine della variabile d'ambiente @env{AWKPATH}. + +@cindex @command{gawklibpath_default}, funzione della shell +@cindex funzione della shell @command{gawklibpath_default} +@item gawklibpath_default +Reimposta la variabile d'ambiente @env{AWKLIBPATH} al suo valore di default. + +@cindex @command{gawklibpath_prepend}, funzione della shell +@cindex funzione della shell @command{gawklibpath_prepend} +@item gawklibpath_prepend +Aggiunge l'argomento all'inizio della variabile d'ambiente +@env{AWKLIBPATH}. + +@cindex @command{gawklibpath_append}, funzione della shell +@cindex funzione della shell @command{gawklibpath_append} +@item gawklibpath_append +Aggiunge l'argomento alla fine della variabile d'ambiente +@env{AWKLIBPATH}. + +@end table + + +@node Ulteriori opzioni di configurazione +@appendixsubsec Ulteriori opzioni di configurazione +@cindex @command{gawk}, configurazione, opzioni di +@cindex configurazione di @command{gawk}, opzioni di + +Ci sono parecchie altre opzioni che si possono utilizzare sulla riga +di comando di @command{configure} +quando si compila @command{gawk} a partire dai sorgenti, tra cui: + +@table @code + +@cindex @option{--disable-extensions}, opzione di configurazione +@cindex opzione di configurazione @code{--disable-extensions} +@item --disable-extensions +Richiede di non configurare e generare le estensioni di esempio nella +directory @file{extension}. Questo @`e utile quando si genera +@command{gawk} per essere eseguito su un'altra piattaforma. +L'azione di default @`e di controllare dinamicamente se le estensioni +possono essere configurate e compilate. + +@cindex @option{--disable-lint}, opzione di configurazione +@cindex opzione di configurazione @code{--disable-lint} +@item --disable-lint +Disabilita i controlli @dfn{lint} all'interno di @command{gawk}. Le opzioni +@option{--lint} e @option{--lint-old} +(@pxref{Opzioni}) +sono accettate, ma non fanno nulla, e non emettono alcun messaggio di +avvertimento. +Analogamente, se si imposta la variabile @code{LINT} +(@pxref{Variabili modificabili dall'utente}) +questa non ha alcun effetto sul programma @command{awk} in esecuzione. + +Se si specifica l'opzione del compilatore GNU Compiler Collection (GCC) che +elimina il codice non eseguito, quest'opzione riduce di quasi +23K byte la dimensione del programma eseguibile @command{gawk} +su sistemi GNU/Linux x86_64. I risultati su altri sistemi e con +altri compilatori sono probabilmente diversi. +L'uso di questa opzione pu@`o apportare qualche piccolo miglioramento nei +tempi di esecuzione di un programma. + +@quotation ATTENZIONE +Se si usa quest'opzione alcuni dei test di funzionalit@`a non avranno successo. +Quest'opzione potr@`a essere rimossa in futuro. +@end quotation + +@cindex @option{--disable-nls}, opzione di configurazione +@cindex opzione di configurazione @code{--disable-nls} +@item --disable-nls +Non attiva la traduzione automatica dei messaggi. +Ci@`o normalmente non @`e consigliabile, ma pu@`o apportare qualche lieve +miglioramento nei tempi di esecuzione di un programma. + +@cindex @option{--with-whiny-user-strftime}, opzione di configurazione +@cindex opzione di configurazione @code{--with-whiny-user-strftime} +@item --with-whiny-user-strftime +Forza l'uso della versione della funzione C @code{strftime()} inclusa nella +distribuzione di @command{gawk}, per i sistemi in cui la funzione stessa +non sia disponibile. +@end table + +Si usi il comando @samp{./configure --help} per ottenere la lista completa +delle opzioni disponibili in @command{configure}. + +@node Filosofia della configurazione +@appendixsubsec Il processo di configurazione + +@cindex @command{gawk}, configurazione di +@cindex configurazione di @command{gawk} +Questa @value{SECTION} interessa solo a chi abbia un minimo di familiarit@`a con +il linguaggio C e con i sistemi operativi di tipo Unix. + +Il codice sorgente di @command{gawk}, in generale, cerca di aderire, nei limiti +del possibile, a degli standard formali. Ci@`o significa che @command{gawk} usa +routine di libreria che sono specificate nello standard ISO C e nello standard +POSIX per le interfacce dei sistemi operativi. Il codice sorgente di +@command{gawk} richiede l'uso di un compilatore ISO C (standard 1990). + +Molti sistemi Unix non aderiscono completamente n@'e allo standard ISO n@'e a +quello POSIX. La sottodirectory @file{missing_d} nella distribuzione di +@command{gawk} contiene delle versioni sostitutive per quelle funzioni che pi@`u +frequentemente risultano essere non disponibili. + +Il file @file{config.h} creato da @command{configure} contiene definizioni che +elencano funzionalit@`a del particolare sistema operativo nel quale si tenta di +compilare @command{gawk}. Le tre cose descritte da questo file sono: quali +file di intestazione sono disponibili, in modo da poterli includere correttamente, +quali funzioni (presumibilmente) standard sono realmente disponibili nelle +librerie C, e varie informazioni assortite riguardo al sistema operativo +corrente. Per esempio, pu@`o non esserci l'elemento @code{st_blksize} nella +struttura @code{stat}. In questo caso, @samp{HAVE_STRUCT_STAT_ST_BLKSIZE} @`e +indefinito. + +@cindex @code{custom.h}, file +@`E possible che il compilatore C del sistema in uso "tragga in inganno" +@command{configure}. Pu@`o succedere nel caso in cui non viene restituito +un errore se una funzione di libreria non @`e disponibile. Per superare questo +problema, si pu@`o modificare il file @file{custom.h}. Basta usare una direttiva +@samp{#ifdef} appropriata per il sistema corrente, e definire, tramite +@code{#define}, tutte le costanti che @command{configure} avrebbe dovuto +definire, ma non @`e riuscito a farlo, oppure, usando @code{#undef} annullare le +costanti che @command{configure} ha definito, ma non avrebbe dovuto farlo. Il +file @file{custom.h} @`e automaticamente incluso dal file @file{config.h}. + +@`E anche possibile che il programma @command{configure} generato da Autoconf non +funzioni in un dato sistema per una ragione differente. Se c'@`e un problema, si +tenga presente che il file @file{configure.ac} @`e quello preso in input da +Autoconf. @`E possibile modificare questo file e generare una nuova versione di +@command{configure} che funzioni sul sistema corrente (@pxref{Bug} per +informazioni su come segnalare problemi nella configurazione di +@command{gawk}). Lo stesso meccanismo si pu@`o usare per inviare aggiornamenti +al file @file{configure.ac} e/o a @file{custom.h}. + +@node Installazione non-Unix +@appendixsec Installazione su altri Sistemi Operativi + +Questa @value{SECTION} descrive come installare @command{gawk} su +vari sistemi non-Unix. + +@menu +* Installazione su PC:: Installare e compilare @command{gawk} + su Microsoft Windows. +* Installazione su VMS:: Installare @command{gawk} su VMS. +@end menu + +@node Installazione su PC +@appendixsubsec Installazione su MS-Windows + +@cindex PC, @command{gawk} su sistemi operativi +@cindex sistemi operativi per PC, @command{gawk} su +@cindex installare @command{gawk} su sistemi operativi per PC +Questa @value{SECTION} tratta dell'installazione e uso di @command{gawk} +su macchine con architettura Intel che eseguono qualsiasi versione di +MS-Windows. +In questa @value{SECTION}, il termine ``Windows32'' +si riferisce a una qualsiasi versione di Microsoft Windows +95/98/ME/NT/2000/XP/Vista/7/8/10. + +Si veda anche il file @file{README_d/README.pc} nella distribuzione. + +@menu +* Installazione binaria su PC:: Installare una distribuzione pronta + all'uso. +* Compilazione su PC:: Compilare @command{gawk} per Windows32. +* Uso su PC:: Eseguire @command{gawk} su Windows32. +* Cygwin:: Compilare ed eseguire @command{gawk} + per Cygwin. +* MSYS:: Usare @command{gawk} nell'ambiente MSYS. +@end menu + +@node Installazione binaria su PC +@appendixsubsubsec Installare una distribuzione predisposta per sistemi MS-Windows + +La sola distribuzione binaria predisposta supportata per i sistem MS-Windows +@`e quella messa a disposizione da Eli Zaretskii +@uref{https://sourceforge.net/projects/ezwinports/, progetto ``ezwinports''}. +Si parta da l@`{@dotless{i}} per installare il comando @command{gawk} precompilato. + +@node Compilazione su PC +@appendixsubsubsec Compilare @command{gawk} per sistemi operativi di PC + +@command{gawk} pu@`o essere compilato per Windows32, usando MinGW +(per Windows32). +Il file @file{README_d/README.pc} nella distribuzione @command{gawk} +contiene ulteriori annotazioni, e il file @file{pc/Makefile} contiene +informazioni importanti sulle opzioni di compilazione. + +@cindex compilare @command{gawk} per MS-Windows +Per compilare @command{gawk} per Windows32, occorre copiare i file +dalla directory @file{pc} (@emph{tranne} il file @file{ChangeLog}) alla +directory che contiene il resto dei sorgenti di @command{gawk}, e quindi +chiamare @command{make}, specificando il nome appropriato di obiettivo come +argomento, per generare @command{gawk}. Il @file{Makefile} copiato dalla +directory @file{pc} contiene una sezione di configurazione con commenti, e pu@`o +essere necessario modificarlo perch@'e funzioni con il programma di utilit@`a +@command{make} corrente. + +Il @file{Makefile} contiene un certo numero di alternative, che permettono di +generare @command{gawk} per diverse +versioni MS-DOS e Windows32. Se il comando @command{make} @`e richiamato senza +specificare alcun argomento viene stampata una lista delle alternative +disponibili. Per esempio, +per generare un codice binario di @command{gawk} nativo per MS-Windows +usando gli strumenti MinGW, scrivere @samp{make mingw32}. + +@node Uso su PC +@appendixsubsubsec Usare @command{gawk} su sistemi operativi PC +@cindex PC, @command{gawk} su sistemi operativi +@cindex sistemi operativi PC, @command{gawk} su + +Sotto MS-Windows, gli ambienti Cygwin e MinGW consentono di usare +sia l'operatore @samp{|&} che le operazioni su rete TCP/IP +(@pxref{Reti TCP/IP}). + +@cindex percorso di ricerca +@cindex percorso di ricerca per file sorgente +@cindex @command{gawk}, versione MS-Windows di +@cindex @code{;} (punto e virgola), @env{AWKPATH} variabile e +@cindex punto e virgola (@code{;}), @env{AWKPATH} variabile e +@cindex @env{AWKPATH}, variabile d'ambiente +@cindex variabile d'ambiente @env{AWKPATH} +Le versioni MS-Windows di @command{gawk} ricercano i file di +programma come descritto in @ref{AWKPATH (Variabile)}. Comunque, gli elementi +della variabile @env{AWKPATH} sono separati tra di loro da un punto e virgola +(anzich@'e da due punti (@code{:})). +Se @env{AWKPATH} @`e non impostata o ha per valore la stringa nulla, il percorso +di ricerca di default @`e @samp{@w{.;c:/lib/awk;c:/gnu/lib/awk}}. + +@cindex estensioni comuni, variabile @code{BINMODE} +@c @cindex extensions, common@comma{} @code{BINMODE} variable +@cindex differenze tra @command{awk} e @command{gawk}, variabile @code{BINMODE} +@cindex @code{BINMODE}, variabile +@cindex variabile @code{BINMODE} +Sotto MS-Windows, +@command{gawk} (come molti altri programmi di trattamento testi) converte +automaticamente la stringa di fine riga @samp{\r\n} in @samp{\n} leggendo dall'input +e @samp{\n} in @samp{\r\n} scrivendo sull'output. +La variabile speciale @code{BINMODE} @value{COMMONEXT} permette di controllare +come avvengono queste conversioni, ed @`e interpretata come segue: + +@itemize @value{BULLET} +@item +Se @code{BINMODE} @`e @code{"r"} o uno, +la modalit@`a binaria @`e impostata +in lettura (cio@`e, nessuna conversione in lettura). + +@item +Se @code{BINMODE} @`e @code{"w"} o due, +la modalit@`a binaria @`e impostata +in scrittura (cio@`e, nessuna conversione in scrittura). + +@item +Se @code{BINMODE} @`e @code{"rw"} o @code{"wr"} o tre, +la modalit@`a binaria @`e impostata sia in lettura che in scrittura. + +@item +@code{BINMODE=@var{stringa-non-nulla}} equivale a specificare +@samp{BINMODE=3} (cio@`e, nessuna conversione in +lettura e scrittura). Tuttavia, @command{gawk} emette un messaggio di +avviso se la stringa non @`e @code{"rw"} o @code{"wr"}. +@end itemize + +@noindent +La modalit@`a di trattamento dello standard input e standard output sono +impostate una volta sola +(dopo aver letto la riga di comando, ma prima di iniziare a elaborare +qualsiasi programma @command{awk}). +L'impostazione di @code{BINMODE} per standard input o +standard output va fatta usando +un'appropriata opzione @samp{-v BINMODE=@var{N}} sulla riga di comando. +@code{BINMODE} @`e impostato nel momento in cui un file o @dfn{pipe} @`e aperto +e non pu@`o essere cambiato in corso di elaborazione. + +Il nome @code{BINMODE} @`e stato scelto in analogia con @command{mawk} +(@pxref{Altre versioni}). +@command{mawk} e @command{gawk} gestiscono @code{BINMODE} in maniera simile; +tuttavia, @command{mawk} prevede un'opzione @samp{-W BINMODE=@var{N}} e una +variabile d'ambiente che pu@`o impostare @code{BINMODE}, @code{RS}, e @code{ORS}. +I file @file{binmode[1-3].awk} (nella directory @file{gnu/lib/awk} in alcune +delle distribuzioni binarie gi@`a predisposte) sono stati inclusi per rendere +disponibile l'opzione di @command{mawk} @samp{-W BINMODE=@var{N}}. Questi +possono essere modificati o ignorati; in particolare, quale sia l'impostazione +di @code{RS} che d@`a meno ``sorprese'' rimane una questione aperta. +@command{mawk} usa @samp{RS = "\r\n"} se si imposta la modalit@`a binaria in +lettura, il che @`e appropriato per file che abbiano i caratteri di fine riga in +stile MS-DOS. + +Per chiarire, gli esempi seguenti impostano la modalit@`a binaria in +scrittura per lo standard output e altri file, e impostano @code{ORS} in modo +da ottenere la fine riga ``normale'' in stile MS-DOS: + +@example +gawk -v BINMODE=2 -v ORS="\r\n" @dots{} +@end example + +@noindent +o: + +@example +gawk -v BINMODE=w -f binmode2.awk @dots{} +@end example + +@noindent +Questi comandi danno lo stesso risultato dell'opzione +@samp{-W BINMODE=2} in @command{mawk}. +Quanto segue modifica il separatore di record a @code{"\r\n"} e imposta +la modalit@`a binaria in lettura, senza modificare le letture da standard input: + +@example +gawk -v RS="\r\n" -e "BEGIN @{ BINMODE = 1 @}" @dots{} +@end example + +@noindent +o: + +@example +gawk -f binmode1.awk @dots{} +@end example + +@noindent +Usando i caratteri di protezione appropriati, nel primo +esempio l'impostazione di @code{RS} pu@`o essere spostata in una regola +@code{BEGIN}. + +@node Cygwin +@appendixsubsubsec Usare @command{gawk} in ambiente Cygwin +@cindex compilare @command{gawk} per Cygwin +@cindex Cygwin, compilare @command{gawk} per + +@command{gawk} pu@`o essere compilato e usato ``cos@`{@dotless{i}} com'@`e'' sotto MS-Windows se +si opera all'interno dell'ambiente @uref{http://www.cygwin.com, Cygwin}. +Questo ambiente consente un'eccellente simulazione di GNU/Linux, con l'uso di +Bash, GCC, GNU Make, e altri programmi GNU. La compilazione e l'installazione +per Cygwin @`e la stessa usata nei sistemi di tipo Unix: + +@example +tar -xvpzf gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz +cd gawk-@value{VERSION}.@value{PATCHLEVEL} +./configure +make && make check +@end example + +In confronto a un sistema GNU/Linux sulla stessa macchina, l'esecuzione +del passo di @samp{configure} sotto Cygwin richiede molto pi@`u tempo. Tuttavia +si conclude regolarmente, e poi @samp{make} funziona come ci si aspetta. + +@node MSYS +@appendixsubsubsec Usare @command{gawk} in ambiente MSYS + +Nell'ambiente MSYS sotto MS-Windows, @command{gawk} automaticamente usa la +modalit@`a binaria per leggere e scrivere file. Non @`e quindi necessario usare la +variabile @code{BINMODE}. + +Questo pu@`o causare problemi con altri componenti di tipo Unix che sono stati +resi disponibile in MS-Windows, che si aspettano che @command{gawk} faccia +automaticamente la conversione di @code{"\r\n"}, mentre cos@`{@dotless{i}} non @`e. + +@node Installazione su VMS +@appendixsubsec Compilare e installare @command{gawk} su Vax/VMS e OpenVMS + +@c based on material from Pat Rankin <rankin@eql.caltech.edu> +@c now rankin@pactechdata.com +@c now r.pat.rankin@gmail.com + +@cindex @command{gawk}, versione VMS di +@cindex installare @command{gawk} su VMS +@cindex VMS, installare @command{gawk} su +Questa @value{SUBSECTION} descrive come compilare e installare @command{gawk} +sotto VMS. Il termine classico ``VMS'' @`e usato qui anche per designare +OpenVMS. + +@menu +* Compilazione su VMS:: Come compilare @command{gawk} su VMS. +* Estensioni dinamiche su VMS:: Compilare estensioni dinamiche + di @command{gawk} su VMS. +* Dettagli installazione su VMS:: Come installare @command{gawk} su VMS. +* Esecuzione su VMS:: Come eseguire @command{gawk} su VMS. +* GNV su VMS:: Il progetto VMS GNV. +* Vecchio Gawk su VMS:: Una versione non aggiornata arriva + con alcune versioni di VMS. +@end menu + +@node Compilazione su VMS +@appendixsubsubsec Compilare @command{gawk} su VMS +@cindex compilare @command{gawk} per VMS +@cindex VMS, compilare @command{gawk} per + +Per compilare @command{gawk} sotto VMS, esiste una procedura di comandi +@code{DCL} che esegue tutti i comandi @code{CC} e @code{LINK} necessari. C'@`e +anche un @file{Makefile} da usare con i programmi di utilit@`a @code{MMS} e +@code{MMK}. A partire della directory che contiene i file sorgente, si usi: + +@example +$ @kbd{@@[.vms]vmsbuild.com} +@end example + +@noindent +o: + +@example +$ @kbd{MMS/DESCRIPTION=[.vms]descrip.mms gawk} +@end example + +@noindent +o: + +@example +$ @kbd{MMK/DESCRIPTION=[.vms]descrip.mms gawk} +@end example + +Il comando @command{MMK} @`e un quasi-clone, a codice aperto e gratuito, di +@command{MMS}, che gestisce in maniera migliore i volumi ODS-5 con @value{FNS} +a caratteri maiuscoli e minuscoli. @command{MMK} @`e disponibile da +@uref{https://github.com/endlesssoftware/mmk}. + +Avendo a che fare con volumi ODS-5 e con l'analisi sintattica estesa abilitata, +il nome del parametro che specifica l'obiettivo pu@`o dover essere scritto +digitando esattamente le lettere maiuscole e minuscole. + +@command{gawk} @`e stato testato sotto VAX/VMS 7.3 e Alpha/VMS 7.3-1 usando il +compilatore Compaq C V6.4, e sotto Alpha/VMS 7.3, Alpha/VMS 7.3-2, e IA64/VMS +8.3. Le compilazioni pi@`u recenti hanno usato il compilatore HP C V7.3 su Alpha +VMS 8.3 e su VMS 8.4, sia Alpha che IA64, hanno usato il compilatore HP C +7.3.@footnote{L'architettura IA64 @`e anche nota come ``Itanium''.} + +@xref{GNV su VMS} per informazioni su come compilare +@command{gawk} come un kit PCSI compatible con il prodotto GNV. + +@node Estensioni dinamiche su VMS +@appendixsubsubsec Compilare estensioni dinamiche di @command{gawk} in VMS + +Le estensioni che sono state rese disponibile su VMS possono essere +costruite dando uno dei comandi seguenti: + +@example +$ @kbd{MMS/DESCRIPTION=[.vms]descrip.mms extensions} +@end example + +@noindent +o: + +@example +$ @kbd{MMK/DESCRIPTION=[.vms]descrip.mms extensions} +@end example + +@command{gawk} usa @code{AWKLIBPATH} come una variabile d'ambiente +oppure come un nome logico per trovare le estensioni dinamiche. + +Le estensioni dinamiche devono essere compilate con le stesse opzioni del +compilatore usate per compilare @command{gawk} riguardanti numeri in virgola +mobile, dimensione dei puntatori e trattamento dei nomi simbolici. I computer +con architettura Alpha e Itanium dovrebbero usare i numeri in virgola mobile +col formato IEEE. La dimensione dei puntatori @`e 32 bit, e il trattamento dei nomi +simbolici dovrebbe richiedere il rispetto esatto di maiuscole/minuscole, con le +abbreviazioni CRC per simboli pi@`u lunghi di 32 bit. + +Per Alpha e Itanium: + +@example +/name=(as_is,short) +/float=ieee/ieee_mode=denorm_results +@end example + +Per VAX: + +@example +/name=(as_is,short) +@end example + +Le macro da usare al momento della compilazione devono essere definite prima di +includere il primo file di intestazione proveniente da VMS, come segue: + +@example +#if (__CRTL_VER >= 70200000) && !defined (__VAX) +#define _LARGEFILE 1 +#endif + +#ifndef __VAX +#ifdef __CRTL_VER +#if __CRTL_VER >= 80200000 +#define _USE_STD_STAT 1 +#endif +#endif +#endif +@end example + +Se si scrivono delle estensioni utente da eseguire su VMS, vanno fornite anche +queste definizioni. Il file @file{config.h} creato quando si compila +@command{gawk} su VMS lo fa gi@`a; se invece si usa qualche altro file simile, +occorre ricordarsi di includerlo prima di qualsiasi file di intestazione +proveniente da VMS. + +@node Dettagli installazione su VMS +@appendixsubsubsec Installare @command{gawk} su VMS + +Per usare @command{gawk}, tutto ci@`o che serve @`e un comando ``esterno'', che @`e +un simbolo @code{DCL} il cui valore inizia col segno del dollaro. +Per esempio: + +@example +$ @kbd{GAWK :== $disk1:[gnubin]gawk} +@end example + +@noindent +Si sostituisca la posizione corrente di @command{gawk.exe} a +@samp{$disk1:[gnubin]}. Il simbolo dovrebbe essere posto nel file +@file{login.com} di ogni utente che desideri eseguire @command{gawk}, +in modo che sia definito ogni volta che l'utente inizia una sessione. +Alternativamente, il simbolo pu@`o essere messo nella procedura di sistema +@file{sylogin.com}, +in modo da permettere a tutti gli utenti di eseguire @command{gawk}. + +Se @command{gawk} @`e stato installato da un kit PCSI nell'albero di +directory @file{GNV$GNU:}, il programma avr@`a come nome +@file{GNV$GNU:[bin]gnv$gawk.exe}, e il file di aiuto sar@`a chiamato +@file{GNV$GNU:[vms_help]gawk.hlp}. + +Il kit PCSI installa anche un file @file{GNV$GNU:[vms_bin]gawk_verb.cld} +che pu@`o essere usato per aggiungere @command{gawk} e @command{awk} +alla lista dei comandi DCL. + +Per farlo solo nella sessione corrente si pu@`o usare: + +@example +$ @kbd{set command gnv$gnu:[vms_bin]gawk_verb.cld} +@end example + +Oppure il sistemista VMS pu@`o usare @file{GNV$GNU:[vms_bin]gawk_verb.cld} per +aggiungere @command{gawk} e @command{awk} alla tabella @samp{DCLTABLES} +valida per tutto il sistema. + +La sintassi DCL @`e documentata nel file @file{gawk.hlp}. + +In alternativa, l'elemento @file{gawk.hlp} pu@`o essere caricato in una +libreria di aiuto VMS: + +@example +$ @kbd{LIBRARY/HELP sys$help:helplib [.vms]gawk.hlp} +@end example + +@noindent +(Una libreria specifica dell'installazione potrebbe venir usata invece +della libreria standard VMS library @samp{HELPLIB}.) Dopo aver installato +il testo di aiuto, il comando: + +@example +$ @kbd{HELP GAWK} +@end example + +@noindent +fornisce informazioni sia sull'implementazione di @command{gawk} +sia sul linguaggio di programmazione @command{awk}. + +Il nome logico @samp{AWK_LIBRARY} pu@`o designare una posizione di default per i +file di programma @command{awk}. Riguardo all'opzione @option{-f}, se il +@value{FN} specificato non contiene un dispositivo o un percorso di directory, +@command{gawk} cerca dapprima nella directory corrente, poi nella directory +specificata dalla traduzione di @samp{AWK_LIBRARY} se il file non @`e stato +trovato. Se, dopo aver cercato in entrambe queste directory, il file non @`e +ancora stato trovato, @command{gawk} appone il suffisso @samp{.awk} al +@value{FN} e ritenta la ricerca del file. Se @samp{AWK_LIBRARY} non @`e +definita, si usa per essa il valore di default @samp{SYS$LIBRARY:}. + +@node Esecuzione su VMS +@appendixsubsubsec Eseguire @command{gawk} su VMS + +L'elaborazione della riga di comando e le convenzioni per proteggere i +caratteri sono significativamente differenti in VMS, e quindi gli esempi +presenti in questo @value{DOCUMENT} o provenienti da altre fonti necessitano +piccole modifiche. Le modifiche, tuttavia, @emph{sono} veramente piccole, e +tutti i programmi @command{awk} dovrebbero funzionare correttamente. + +Ecco un paio di semplici test: + +@example +$ @kbd{gawk -- "BEGIN @{print ""Hello, World!""@}"} +$ @kbd{gawk -"W" version} +! ma anche -"W version" o "-W version" +@end example + +@noindent +Si noti che il testo con caratteri maiuscoli e misti maiuscoli/minuscoli +dev'essere incluso tra doppi apici. + +La versione VMS di @command{gawk} comprende un'interfaccia in stile @code{DCL}, +oltre a quella originale, di tipo shell (si veda il file di aiuto per ulteriori +dettagli). Un effetto indesiderato della duplice analisi della riga +di comando @`e che se c'@`e solo un unico parametro (come nel programma con le +righe contenenti doppi apici), il comando diviene ambiguo. Per evitare questo +inconveniente, il flag, normalmente non necessario, @option{--} @`e necessario +per forzare un esame dei parametri in stile Unix, piuttosto che nella modalit@`a +@code{DCL}. Se qualsiasi altra opzione preceduta dal segno @option{-} (o pi@`u +parametri, per esempio, pi@`u @value{DF} in input) @`e presente, non c'@`e ambiguit@`a, +e l'opzione @option{--} pu@`o essere omessa. + +@cindex exit, codice di ritorno, in VMS +Il valore di @code{exit} @`e un valore in stile Unix e viene trasformato in +una condizione VMS all'uscita del programma. + +I bit di severit@`a di VMS saranno impostati a partire dal valore dell'istruzione +@code{exit}. Un errore grave @`e indicato da 1, e VMS imposta la condizione +@code{ERROR}. Un errore fatale @`e indicato da 2, e VMS imposta la condizione +@code{FATAL}. Ogni altro valore imposta la condizione @code{SUCCESS}. Il +valore d'uscita @`e codificato per aderire agli standard di codifica VMS e avr@`a +un @code{C_FACILITY_NO} di @code{0x350000} con il codice costante @code{0xA000} +aggiunto al numero spostato a sinistra di 3 bit per far posto al codice di +severit@`a. + +Per estrarre il codice reale di ritorno dell'istruzione @code{exit} +di @command{gawk} dalla condizione impostata da VMS, si usi: + +@example +unix_status = (vms_status .and. %x7f8) / 8 +@end example + +@noindent +Un programma C che usa @code{exec()} per chiamare @command{gawk} +ricever@`a il valore originale della exit in stile Unix. + +Precedenti versioni di @command{gawk} per VMS consideravano un codice di +ritorno a Unix di 0 come 1, un errore come 2, un errore fatale come 4, e tutti +gli altri valori erano restituiti immodificati. Questa era una violazione +rispetto alle specifiche di codifica delle condizioni di uscita di VMS. + +@cindex numeri in virgola mobile, VAX/VMS +@cindex VAX/VMS, numeri in virgola mobile, +L'aritmetica in virgola mobile VAX/VMS usa un arrotondamento statistico. +@xref{Funzione round}. + +VMS restituisce data e ora in formato GMT, a meno che non siano stati impostati +i nomi logici @code{SYS$TIMEZONE_RULE} o @code{TZ}. Precedenti versioni di +VMS, come VAX/VMS 7.3, non impostano questi nomi logici. + +@c @cindex directory search +@c @cindex path, search +@cindex percorso di ricerca +@cindex percorso di ricerca per file sorgente +Il percorso di ricerca di default, nella ricerca dei file di programma per +@command{awk} specificati dall'opzione @option{-f}, @`e +@code{"SYS$DISK:[],AWK_LIBRARY:"}. Il nome logico @env{AWKPATH} pu@`o essere +usato per sostituire questo di default. Il formato di @env{AWKPATH} @`e una lista +di directory, separate da virgola. Nel definirla, il valore dovrebbe essere +incluso tra doppi apici, in modo che consenta una sola traduzione, e non una +lista di ricerca multitraduzione @code{RMS}. + +@cindex ridirezione in VMS + +Questa restrizione vale anche se si esegue @command{gawk} sotto GNV, +in quanto la ridirezione @`e sempre verso un comando DCL. + +Se si ridirigono dati verso un comando o un programma di utilit@`a VMS, +l'implementazione corrente richiede la creazione di un comando VMS esterno che +esegua un file di comandi, prima di invocare @command{gawk}. +(Questa restrizione potrebbe essere rimossa in una futura versione di +@command{gawk} per VMS.) + +Senza un tale file di comandi, i dati in input saranno presenti anche +in output, prima dei dati di output veri e propri. + +Ci@`o consente la simulazione di comandi POSIX non disponibili in VMS +o l'uso di programmi di utilit@`a GNV. + +L'esempio seguente mostra come ridirigere dati da @command{gawk} verso il +comando VMS @command{sort}. + +@example +$ sort = "@@device:[dir]vms_gawk_sort.com" +@end example + +Il file di comandi deve avere il formato dell'esempio seguente. + +La prima riga serve a evitare che i dati in input siano presenti anche +nell'output. Dev'essere nel formato mostrato nell'esempio. + +La riga seguente crea un comando esterno che prevale sul comando esterno +superiore, che serve a prevenire una ricorsione infinita di file di comandi. + +Il penultimo comando ridirige @code{sys$input} su @code{sys$command}, +per poter ottenere i dati che sono ridiretti verso il comando. + +L'ultima riga esegue il comando vero e proprio. Dev'essere l'ultimo +comando, perch@'e i dati ridiretti da @command{gawk} saranno letti +quando il file di comandi finisce di essere eseguito. + +@example +$!'f$verify(0,0)' +$ sort := sort +$ define/user sys$input sys$command: +$ sort sys$input: sys$output: +@end example + + +@node GNV su VMS +@appendixsubsubsec Il progetto VMS GNV + +Il pacchetto VMS GNV fornisce un ambiente di sviluppo simile +a POSIX tramite una collezione di strumenti @dfn{open source}. +Il @command{gawk} presente nel pacchetto base GNV @`e una vecchia versione. +Attualmente, il progetto GNV @`e in fase di riorganizzazione, con l'obiettivo +di offrire pacchetti PCSI separati per ogni componente. +Si veda @w{@uref{https://sourceforge.net/p/gnv/wiki/InstallingGNVPackages/}.} + +La procedura normale per compilare @command{gawk} produce un programma +adatto a essere usato con GNV. + +Il file @file{vms/gawk_build_steps.txt} nella distribuzione documenta +la procedura per compilare un pacchetto PCSI compatible con GNV. + +@ignore +@c The VMS POSIX product, also known as POSIX for OpenVMS, is long defunct +@c and building gawk for it has not been tested in many years, but these +@c old instructions might still work if anyone is still using it. + +@node VMS POSIX +@appendixsubsubsec Compilare e usare @command{gawk} su VMS POSIX + +Le istruzioni appena viste vanno ignorate, sebbene @file{vms/gawk.hlp} +dovrebbe ancora essere reso disponibile in una libreria di aiuto. +L'albero del codice sorgente dovrebbe essere scompattato in un sottosistema +contenitore di file, e non nel normale @dfn{filesystem} VMS. +Occorre accertarsi che i due script, @file{configure} e +@file{vms/posix-cc.sh}, siano eseguibile; si usi @samp{chmod +x} per farlo, +se necessario. Poi vanno eseguiti i seguenti due comandi: + +@example +psx> @kbd{CC=vms/posix-cc.sh configure} +psx> @kbd{make CC=c89 gawk} +@end example + +@noindent +Il primo comando costruisce i file @file{config.h} e @file{Makefile}, +a partire da dei modelli, usando uno script per fare s@`{@dotless{i}} che il +compilatore C soddisfi le aspettative di @command{configure}. Il secondo +comando compila e collega @command{gawk} chiamando direttamente il +compilatore C; gli eventuali messaggi di @command{make} che dicono di non +riuscire a ridefinire @code{CC} vanno ignorati. @command{configure} +impiega molto tempo a completarsi, ma in compenso continua a fornire +messaggi che permettono di seguirne l'avanzamento. + +Questo @`e stato testato con VAX/VMS V6.2, VMS POSIX V2.0, e DEC C V5.2. + +Una volta installato, @command{gawk} funziona come ogni altro programma +di utilit@`a della shell. A differenza della normale versione VMS di +@command{gawk}, neesuna manipolazione speciale della riga di comando @`e +necessaria nell'ambiente VMS POSIX. +@end ignore + +@node Vecchio Gawk su VMS +@appendixsubsubsec Vecchia versione di @command{gawk} su sistemi VMS + + +@c Thanks to "gerard labadie" <gerard.labadie@gmail.com> + +Alcune versioni di VMS includono una vecchia versione di @command{gawk}. +Per utilizzarla, occorre definire un simbolo, come segue: + +@example +$ @kbd{gawk :== $sys$common:[syshlp.examples.tcpip.snmp]gawk.exe} +@end example + +La versione appare essere la @value{PVERSION} 2.15.6, che @`e molto vecchia. +Si raccomanda di compilare e usare la versione corrente. + +@node Bug +@appendixsec Segnalazione di problemi e bug +@cindex archeologi +@quotation +@i{Non c'@`e niente di pi@`u pericoloso di un archeologo annoiato.} +@author Douglas Adams, @cite{Guida galattica per autostoppisti} +@end quotation +@c the radio show, not the book. :-) + +@cindex debug, @command{gawk}, segnalare bug +@cindex risoluzione problemi @command{gawk}, segnalare bug +Se si incontrano problemi con @command{gawk} o se si ritiene di aver trovato un +bug, si raccomanda di segnalarlo agli sviluppatori; +non c'@`e un impegno preciso a intervenire, ma c'@`e una buona possibilit@`a che ci +si sforzi di risolverlo. + +@menu +* Indirizzo Bug:: Dove inviare le segnalazioni. +* Usenet:: Dove non inviare le segnalazioni. +* Manutentori:: Manutentori di version non-*nix. +@end menu + +@node Indirizzo Bug +@appendixsubsec Segnalare Bug + +Prima di segnalare un bug, occorre assicurarsi che sia davvero un bug. La +documentazione va riletta attentamente, per controllare se dice che @`e possibile +fare quel che si sta tentando di fare. Se non @`e chiaro se sia possibile +fare quella particolare cosa o no, occorre segnalarlo; in questo caso si tratta +di un bug nella documentazione! + +Prima di segnalare un bug o di tentare di risolverlo personalmente, si tenti +di isolarlo preparando un programma @command{awk} il pi@`u piccolo possibile, con +un @value{DF} in input che possa riprodurre il problema. Dopo averlo fatto, si +spedisca il programma e il @value{DF}, insieme a informazioni sul tipo di +sistema Unix in uso, il compilatore usato per compilare @command{gawk}, e i +risultati esatti che @command{gawk} ha prodotto. Inoltre andrebbe specificato +cosa ci si aspettava che il programma facesse; questo @`e di aiuto per decidere +se il problema @`e un problema di documentazione. + +@`E importante includere il numero di versione di @command{gawk} in uso. +Questa informazione si pu@`o ottenere con il comando @samp{gawk --version}. + +@cindex @code{bug-gawk@@gnu.org} indirizzo per la segnalazione dei bug +@cindex email, indirizzo per segnalare bug, @code{bug-gawk@@gnu.org} +@cindex indirizzo email per segnalare bug, @code{bug-gawk@@gnu.org} +@cindex bug, segnalare, indirizzo email, @code{bug-gawk@@gnu.org} +@cindex segnalare bug, indirizzo email, @code{bug-gawk@@gnu.org} +Una volta pronta la descrizione precisa del problema, si spedisca un messaggio +di posta elettronica a @EMAIL{bug-gawk@@gnu.org,bug-gawk at gnu dot org}. + +I manutentori di @command{gawk} sono i destinatari, e riceveranno la +segnalazione di errore. Sebbene sia possibile spedire messaggi direttamente ai +manutentori, @`e preferibile usare l'indirizzo sopra fornito perch@'e quella +mailing list rimane in archivio presso il Progetto GNU. @emph{Tutti i messaggi +devono essere in inglese. @`E questo il solo linguaggio che tutti i manutentori +conoscono.} Inoltre, occorre accertarsi di spedire tutti i messaggi in formato +@emph{testo}, e non (o non soltanto) in formato HTML. + +@quotation NOTA +Molte distribuzioni di GNU/Linux e i vari sistemi operativi basati su +BSD hanno un loro proprio canale per segnalare i bug. Se si segnala un +bug usando il canale della distribuzione, una copia del messaggio andrebbe +inviata anche a @EMAIL{bug-gawk@@gnu.org,bug-gawk at gnu dot org}. + +Questo per due ragioni. La prima @`e che, sebbene alcune distribuzioni inoltrino +i messaggi sui problemi ``verso l'alto'' alla mailing list GNU, molte non lo +fanno, e quindi c'@`e una buona probabilit@`a che i manutentori di @command{gawk} +non vedano affatto il messaggio relativo al bug! La seconda ragione @`e che la +posta diretta alla mailing list GNU @`e archiviata, e il poter disporre di ogni +cosa all'interno del progetto GNU consente di avere a disposizione tutte le +informazioni rilevanti senza dover dipendere da altre organizzazioni. +@end quotation + +Suggerimenti non correlati a bug sono pure sempre benvenuti. Se si hanno +domande riguardo a qualcosa di non chiaro nella documentazione o a proposito +di funzionalit@`a oscure, si scriva alla mailing list dei bug; si prover@`a +a essere di aiuto nei limiti del possibile. + +@node Usenet +@appendixsubsec Non segnalare bug a USENET! + +@quotation +@c Date: Sun, 17 May 2015 19:50:14 -0400 +@c From: Chet Ramey <chet.ramey@case.edu> +@c Reply-To: chet.ramey@case.edu +@c Organization: ITS, Case Western Reserve University +@c To: Aharon Robbins <arnold@skeeve.com> +@c CC: chet.ramey@case.edu +Ho iniziato a ignorare Usenet un paio di anni fa, e non me ne sono mai +pentito. @`E come quando si parla di sport alla radio---ci si sente +pi@`u intelligenti per aver lasciato perdere. +@author Chet Ramey +@end quotation + +@cindex @code{comp.lang.awk} gruppo di discussione +@cindex newsgroup @code{comp.lang.awk} +@cindex gruppo di discussione @code{comp.lang.awk} +Siete pregati di @emph{non} provare a notificare bug di @command{gawk} +scrivendo al gruppo di discussione Usenet/Internet @code{comp.lang.awk}. +Sebbene alcuni degli sviluppatori di @command{gawk} leggano talora i +messaggi di questo gruppo di discussione, il manutentore principale di +@command{gawk} non lo fa pi@`u. Quindi @`e praticamente certo che un +messaggio inviato l@`a @emph{non} sia da lui letto. +La procedura qui descritta @`e la sola maniera ufficialmente riconosciuta +per notificare problemi. Davvero! + +@ignore +And another one: + +Date: Thu, 11 Jun 2015 09:00:56 -0400 +From: Chet Ramey <chet.ramey@case.edu> + +My memory was imperfect. Back in June 2009, I wrote: + +"That's the nice thing about open source, right? You can take your ball +and run to another section of the playground. Then, if you like mixing +metaphors, you can throw rocks from there." +@end ignore + +@node Manutentori +@appendixsubsec Notificare problemi per versioni non-Unix + +Se si riscontrano bug in una delle versioni non-Unix di @command{gawk}, una +copia del messaggio inviato alla mailing list dei bug andrebbe spedita alla +persona che si occupa di quella versione. I manutentori sono elencati nella +lista seguente, come pure nel file @file{README} nella distribuzione +@command{gawk}. Le informazioni nel file @file{README} dovrebbero essere +considerate come le pi@`u aggiornate, se risultano in conflitto con questo +@value{DOCUMENT}. + +Le persone che si occupano delle varie versioni di @command{gawk} sono: + +@c put the index entries outside the table, for docbook +@cindex Buening, Andreas +@cindex Deifik, Scott +@cindex Malmberg, John E. +@cindex Pitts, Dave +@cindex G., Daniel Richard +@cindex Robbins, Arnold +@cindex Zaretskii, Eli +@ifset SMALLPRINT +@multitable {MS-Windows} {123456789012345678901234567890123456789001234567890} +@end ifset +@ifclear SMALLPRINT +@multitable {MS-Windows con MinGW} {123456789012345678901234567890123456789001234567890} +@end ifclear +@item Unix e sistemi POSIX @tab Arnold Robbins, @EMAIL{arnold@@skeeve.com,arnold at skeeve dot com} + +@c @item MS-DOS con DJGPP @tab Scott Deifik, @EMAIL{scottd.mail@@sbcglobal.net,scottd dot mail at sbcglobal dot net} + +@item MS-Windows con MinGW @tab Eli Zaretskii, @EMAIL{eliz@@gnu.org,eliz at gnu dot org} + +@c Leave this in the document on purpose. +@c OS/2 is not mentioned anywhere else though. +@item OS/2 @tab Andreas Buening, @EMAIL{andreas.buening@@nexgo.de,andreas dot buening at nexgo dot de} + +@item VMS @tab John Malmberg, @EMAIL{wb8tyw@@qsl.net,wb8tyw at qsl.net} + +@item z/OS (OS/390) @tab Daniel Richard G.@: @EMAIL{skunk@@iSKUNK.ORG,skunk at iSKUNK.ORG} +@item @tab Dave Pitts (Maintainer Emeritus), @EMAIL{dpitts@@cozx.com,dpitts at cozx dot com} +@end multitable + +Se il problema riscontrato @`e riproducibile anche sotto Unix, +si dovrebbe spedire una copia del messaggio anche alla mailing list +@EMAIL{bug-gawk@@gnu.org,bug-gawk at gnu dot org}. + +La versione generata usando gli strumenti DJGPP non @`e pi@`u supportata; +il codice relativo rester@`a nella distribuzione ancora per qualche tempo, +nel caso che qualche volontario desideri prenderla in carico. +Se questo non dovesse succedere, la parte di codice relativa questa +versione sar@`a rimossa dalla distribuzione. + +@node Altre versioni +@appendixsec Altre implementazioni di @command{awk} liberamente disponibili +@cindex @command{awk}, implementazioni di +@cindex implementazioni di @command{awk} +@ignore +From: emory!amc.com!brennan (Michael Brennan) +Subject: C++ comments in awk programs +To: arnold@gnu.ai.mit.edu (Arnold Robbins) +Date: Wed, 4 Sep 1996 08:11:48 -0700 (PDT) + +@end ignore +@cindex Brennan, Michael +@ifnotdocbook +@quotation +@i{@`E piuttosto divertente mettere commenti simili nel vostro codice awk:}@* +@ @ @ @ @ @ @code{// Funzionano i commenti in stile C++? Risposta: s@`{@dotless{i}}! certo} +@author Michael Brennan +@end quotation +@end ifnotdocbook + +@docbook +<blockquote><attribution>Michael Brennan</attribution> +<literallayout><emphasis> +@`E piuttosto divertente mettere commenti simili nel vostro codice awk. +</emphasis> + <literal> +// Funzionano i commenti in stile C++? Risposta: s@`{@dotless{i}}! certo +</literal></literallayout> +</blockquote> +@end docbook + +Ci sono alcune altre implementazioni di @command{awk} disponibili +gratuitamente. +Questa @value{SECTION} descrive in breve dove @`e possibile trovarle: + +@table @asis +@cindex Kernighan, Brian +@cindex sorgente, codice, Brian Kernighan @command{awk} +@cindex codice sorgente, Brian Kernighan @command{awk} +@cindex @command{awk}, versioni di, si veda anche Brian Kernighan, @command{awk} di +@cindex Brian Kernighan, @command{awk} di, codice sorgente +@item Unix @command{awk} +Brian Kernighan, uno degli sviluppatori originali di Unix @command{awk}, +ha reso disponibile liberamente la sua implementazione di @command{awk}. +Si pu@`o scaricare questa versione dalla +@uref{http://www.cs.princeton.edu/~bwk, sua pagina principale}. +@`E disponibile in parecchi formati compressi: + +@table @asis +@item Archivio Shell +@uref{http://www.cs.princeton.edu/~bwk/btl.mirror/awk.shar} + +@item File @command{tar} compresso +@uref{http://www.cs.princeton.edu/~bwk/btl.mirror/awk.tar.gz} + +@item File Zip +@uref{http://www.cs.princeton.edu/~bwk/btl.mirror/awk.zip} +@end table + +@cindex @command{git}, programma di utilit@`a +@cindex programma di utilit@`a @command{git} +@`E anche disponbile in GitHub: + +@example +git clone git://github.com/onetrueawk/awk bwkawk +@end example + +@noindent +Questo comando crea una copia del deposito @uref{http://git-scm.com, Git} +in una directory chiamata @file{bwkawk}. Se si omette questo argomento della +riga di comando @command{git}, la copia del deposito @`e creata nella +directory di nome @file{awk}. + +Questa versione richiede un compilatore ISO C (standard 1990); il compilatore +C contenuto in GCC (la collezione di compilatori GNU) @`e pi@`u che sufficiente. + +@xref{Estensioni comuni} +per una lista di estensioni in questo @command{awk} che non sono in +POSIX @command{awk}. + +Incidentalmente, Dan Bornstein ha creato un deposito Git che contiene tutte le +versioni di BWK @command{awk} che @`e riuscito a trovare. @`E disponibile in +@uref{git://github.com/danfuzz/one-true-awk}. + +@cindex Brennan, Michael +@cindex @command{mawk}, programma di utilit@`a +@cindex programma di utilit@`a @command{mawk} +@cindex codice sorgente, @command{mawk} +@item @command{mawk} +Michael Brennan ha scritto un'implementazione indipendente di @command{awk}, +di nome @command{mawk}. @`E disponibile sotto la licenza +@ifclear FOR_PRINT +GPL (@pxref{Copia}), +@end ifclear +@ifset FOR_PRINT +GPL, +@end ifset +proprio come @command{gawk}. + +Il sito di distribuzione originale di @command{mawk} non contiene pi@`u +il codice sorgente. Una copia @`e disponibile in +@uref{http://www.skeeve.com/gawk/mawk1.3.3.tar.gz}. + +Dal 2009 @`e Thomas Dickey a occuparsi della manutenzione di @command{mawk}. +Le informazioni di base sono disponibili nella +@uref{http://www.invisible-island.net/mawk, pagine web del progetto}. +Il puntatore URL da cui scaricare @`e +@url{http://invisible-island.net/datafiles/release/mawk.tar.gz}. + +Una volta scaricato, +per scompattare questo file pu@`o essere usato @command{gunzip}. +L'installazione @`e simile a quella di @command{gawk} +(@pxref{Installazione Unix}). + +@xref{Estensioni comuni} +per una lista di estensioni in @command{mawk} che non sono in POSIX @command{awk}. + +@cindex Sumner, Andrew +@cindex @command{awka}, compilatore per @command{awk} +@cindex compilatore per @command{awk}, @command{awka} +@cindex sorgente, codice, @command{awka} +@cindex codice sorgente di @command{awka} +@item @command{awka} +Scritto da Andrew Sumner, +@command{awka} traduce i programmi @command{awk} in C, li compila, +e prepara il codice eseguibile usando una libreria di funzioni che +implementano le funzionalit@`a di base di @command{awk}. +Comprende anche un certo numero di estensioni. + +Il traduttore di @command{awk} @`e rilasciato sotto la licenza GPL, e la +relativa libreria sotto la licenza LGPL. + +Per ottenere @command{awka}, si visiti +il sito @url{http://sourceforge.net/projects/awka}. +@c You can reach Andrew Sumner at @email{andrew@@zbcom.net}. +@c andrewsumner@@yahoo.net + +Il progetto sembra essere stato congelato; non ci sono state modifiche nel +codice sorgente dal 2001 circa. + +@cindex Beebe, Nelson H.F.@: +@cindex @command{pawk} (versione con profilatura di Brian Kernighan @command{awk}) +@cindex codice sorgente, @command{pawk} +@cindex sorgente, codice, @command{pawk} +@item @command{pawk} +Nelson H.F.@: Beebe all'Universit@`a dello Utah ha modificato +BWK @command{awk} per fornire informazioni di temporizzazione e profilatura. +Questo @`e differente dall'usare @command{gawk} con l'opzione @option{--profile} +(@pxref{Profilare}) +nel senso che fornisce un profilo basato sul consumo di CPU, non sul +numero di esecuzioni di una data riga di codice. +Sia pu@`o trovare sia in +@uref{ftp://ftp.math.utah.edu/pub/pawk/pawk-20030606.tar.gz} +che in +@uref{http://www.math.utah.edu/pub/pawk/pawk-20030606.tar.gz}. + +@item BusyBox @command{awk} +@cindex BusyBox Awk +@cindex codice sorgente, BusyBox Awk +@cindex sorgente, codice, BusyBox Awk +BusyBox @`e un programma distribuito con licenza GPL che fornisce versioni +ridotte di parecchie piccole applicazioni, all'interno di un singolo modulo +eseguibile. @`E stato ideato per sistemi +integrati. +Include un'implementazione completa di POSIX @command{awk}. Quando lo si +compila occorre prestare attenzione a non eseguire @samp{make install}, perch@'e +in questo modo si andrebbero a sostituire copie di altre applicazioni nella +directory @file{/usr/local/bin} del sistema corrente. Per ulteriori +informazioni, si veda @uref{http://busybox.net, la pagina principale del progetto}. + +@cindex OpenSolaris +@cindex Solaris, versione POSIX @command{awk} +@cindex codice sorgente, Solaris @command{awk} +@cindex sorgente, codice, Solaris @command{awk} +@item POSIX @command{awk} per OpenSolaris +Le versioni di @command{awk} in @file{/usr/xpg4/bin} e @file{/usr/xpg6/bin} su +Solaris sono @dfn{grosso modo} conformi allo standard POSIX. Sono basate sul +comando @command{awk} preparato per i PC dalla ditta Mortice Kern. @`E stato +possibile compilare e far funzionare questo codice sotto GNU/Linux dopo 1--2 +ore di lavoro. Rendere questo codice pi@`u generalmente portabile (usando gli +strumenti GNU Autoconf e/o Automake) richiederebbe ulteriore lavoro, che non @`e +stato fin qui compiuto, almeno per quel che risulta a chi scrive. + +@cindex Illumos +@cindex Illumos, @command{awk} conforme a POSIX e +@cindex codice sorgente, Illumos @command{awk} +@cindex sorgente, codice, Illumos @command{awk} +Il codice sorgente era un tempo disponibile dal sito web OpenSolaris. +Tuttavia, il progetto @`e terminato, e il sito web chiuso. Fortunatamente, +il progetto +@uref{http://wiki.illumos.org/display/illumos/illumos+Home, Illumos} +mette a disposizione questa implementazione. Si possono vedere i singoli file in +@uref{https://github.com/joyent/illumos-joyent/blob/master/usr/src/cmd/awk_xpg4}. + +@cindex @command{jawk} +@cindex Java, implementazione di @command{awk} +@cindex implementazione Java di @command{awk} +@cindex codice sorgente, @command{jawk} +@cindex sorgente, codice, @command{jawk} +@item @command{jawk} +Questo @`e un interprete per @command{awk} scritto in Java. Dichiara di +essere un interprete completo, anche se, poich@'e usa funzionalit@`a di Java +per l'I/O e per la ricerca di @dfn{regexp}, il linguaggio che supporta +@`e differente da @command{awk} POSIX. +Ulteriori informazioni sono disponibili sulla +@uref{http://jawk.sourceforge.net, pagina principale del progetto}. + +@item Libmawk +@cindex @command{libmawk} +@cindex codice sorgente, @command{libmawk} +@cindex sorgente, codice, @command{libmawk} +Questo @`e un interprete @command{awk} incorporabile, derivato da +@command{mawk}. Per ulteriori informazioni, si veda +@uref{http://repo.hu/projects/libmawk/}. + +@item @code{pawk} +@cindex codice sorgente, @command{pawk} (versione Python) +@cindex sorgente, codice, @command{pawk} (versione Python) +@cindex @code{pawk}, implementazione simile ad @command{awk} per Python +Questo @`e un modulo Python che intende introdurre funzionalit@`a di tipo +@command{awk} in Python. Si veda @uref{https://github.com/alecthomas/pawk} per +ulteriori informazioni. (Questo programma non @`e correlato con la versione +modificata da Nelson Beebe di BWK @command{awk}, descritta prima.) + +@item @w{QSE @command{awk}} +@cindex QSE @command{awk} +@cindex codice sorgente, QSE @command{awk} +@cindex sorgente, codice, QSE @command{awk} +Questo @`e un interprete di @command{awk} incorporabile. Per ulteriori +informazioni, si veda +@uref{http://code.google.com/p/qse/} e @uref{http://awk.info/?tools/qse}. + +@item @command{QTawk} +@cindex QuikTrim Awk +@cindex codice sorgente, QuikTrim Awk +@cindex sorgente, codice, QuikTrim Awk +Questa @`e un'implementazione indipendente di @command{awk} distribuita con la +licenza GPL. Ha un gran numero di estensioni rispetto ad @command{awk} +standard, e pu@`o non essere sintatticamente compatibile al 100% con esso. Si +veda @uref{http://www.quiktrim.org/QTawk.html} per ulteriori informazioni, +compreso il manuale. Il puntatore per scaricare QuikTrim non punta all'ultima +versione: si veda @uref{http://www.quiktrim.org/#AdditionalResources} per un +puntatore alla versione corrente. + +Il progetto sembra essere fermo; non ci sono nuove versioni del codice +a partire dal 2014 circa. + +@item Altre versioni +Si veda anche [in inglese] la sezione ``Versions and implementations'' +della voce di +@uref{http://en.wikipedia.org/wiki/Awk_language#Versions_and_implementations, +Wikipedia} su @command{awk} per informazioni su ulteriori versioni. + +@end table + +@node Sommario dell'installazione +@appendixsec Sommario + +@itemize @value{BULLET} +@item +La distribuzione di @command{gawk} @`e disponibile dal sito principale +di distribuzione del Progetto GNU +@code{ftp.gnu.org}. La maniera canonica per scaricarlo e installarlo @`e: + +@example +wget http://ftp.gnu.org/gnu/gawk/gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz +tar -xvpzf gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz +cd gawk-@value{VERSION}.@value{PATCHLEVEL} +./configure && make && make check +@end example + +@item +@command{gawk} pu@`o essere installato anche su sistemi non-POSIX. I sistemi +correntemente supportati sono MS-Windows, usando +MSYS, MinGW, e Cygwin, +e sia Vax/VMS che OpenVMS. Le istruzioni per ognuno di questi sistemi sono +incluse in questa @value{APPENDIX}. + +@item +Le segnalazioni di errori (bug) dovrebbero essere spedite tramite email a +@email{bug-gawk@@gnu.org}. Le segnalazioni di errore dovrebbero essere scritte +in inglese e dovrebbero specificare la versione di @command{gawk} in uso, come +@`e stata compilata, un breve programma e un @value{DF} che permettono di +riprodurre il problema. + +@item +Ci sono alcune altre implementazioni di @command{awk} disponibili +gratuitamente. Molte rispettano lo standard POSIX; altre un po' meno. + +@end itemize + + +@ifclear FOR_PRINT +@node Note +@appendix Note di implementazione +@cindex @command{gawk}, problemi di implementazione +@cindex problemi di implementazione, @command{gawk} + +Quest'appendice contiene informazioni che interessano soprattutto le persone +che aggiornano e mantengono @command{gawk}. L'intero contenuto si applica +specificatamente a @command{gawk} e non ad altre implementazioni. + +@menu +* Modalit@`a di compatibilit@`a:: Come inibire alcune estensioni di + @command{gawk}. +* Aggiunte:: Fare aggiunte a @command{gawk}. +* Future estensioni:: Nuove funzionalit@`a che potranno + essere implementate in futuro. +* Limitazioni dell'implementazione:: Alcune limitazioni + dell'implementazione. +* Progetto delle estensioni:: Note di progetto sull'estensione API. +* Meccanismo delle vecchie estensioni:: Alcune compatibilit@`a per le vecchie + estensioni. +* Sommario delle note:: Sommario delle note di + implementazione. +@end menu + +@node Modalit@`a di compatibilit@`a +@appendixsec Compatibilit@`a all'indietro e debug +@cindex @command{gawk}, problemi di implementazione, compatibilit@`a all'indietro +@cindex @command{gawk}, problemi di implementazione, debug +@cindex risoluzione di problemi, @command{gawk} +@cindex problemi, risoluzione di, @command{gawk} +@cindex problemi di implementazione@comma{} @command{gawk}, debug + +@xref{POSIX/GNU}, +per un compendio delle estensioni GNU per il linguaggio e il programma +@command{awk}. Tutte queste funzionalit@`a possono essere inibite invocando +@command{gawk} con l'opzione @option{--traditional} o con l'opzione +@option{--posix}. + +Se @command{gawk} @`e stato compilato per il debug con @samp{-DDEBUG}, @`e +possibile specificare un'ulteriore opzione sulla riga di comando: + +@table @code +@item -Y +@itemx --parsedebug +Stampa l'informazione contenuta nella pila di analisi, durante la fase di +analisi iniziale del programma. +@end table + +Quest'opzione @`e utile solo a chi sviluppa @command{gawk} e non all'utente +occasionale. @`E probabile che non sia neppure disponibile nella versione di +@command{gawk} che si sta usando, perch@'e rallenta l'esecuzione del programma. + +@node Aggiunte +@appendixsec Fare aggiunte a @command{gawk} + +Se si desidera migliorare @command{gawk} in maniera significativa, c'@`e la +massima libert@`a di farlo. @`E questo lo scopo del software libero; il codice +sorgente @`e disponibile, ed @`e possibile modificarlo a piacere +(@pxref{Copia}). + +@ifnotinfo +Questa +@end ifnotinfo +@ifinfo +Questo +@end ifinfo +@value{SECTION} tratta di come @`e possibile modificare @command{gawk}, +ed espone alcune considerazioni che si dovrebbero tenere presenti. + +@menu +* Accedere ai sorgenti:: Accedere al deposito dei sorgenti Git. +* Aggiungere codice:: Aggiungere codice al programma + principale @command{gawk}. +* Nuovi sistemi:: Portare @command{gawk} su un nuovo sistema + operativo. +* File derivati:: Perch@'e i file derivati sono tenuti + nel deposito @command{git}. +@end menu + +@node Accedere ai sorgenti +@appendixsubsec Accedere al deposito dei sorgenti Git di @command{gawk} + +Poich@'e @command{gawk} @`e Software Libero, il codice sorgente @`e sempre +disponibile. +@iftex +La +@end iftex +@ref{Distribuzione di Gawk} descrive come scaricare e installare +le versioni ufficiali rilasciate di @command{gawk}. + +@cindex @command{git}, programma di utilit@`a +@cindex programma di utilit@`a @command{git} +Peraltro, se si intende modificare @command{gawk} e mettere a disposizione le +modifiche, @`e preferibile lavorare sulla versione in via di sviluppo. Per far +ci@`o @`e necessario accedere al deposito del codice sorgente di @command{gawk}. +Il codice @`e mantenuto usando il @uref{http://git-scm.com, sistema distribuito +di controllo delle versioni Git}. Sar@`a necessario installarlo se non @`e gi@`a +presente nel sistema. Quando @command{git} @`e disponibile, va usato il comando: + +@example +git clone git://git.savannah.gnu.org/gawk.git +@end example + +@noindent +Questo comando scarica in locale una copia esatta del deposito dei +sorgenti di @command{gawk}. Se si sta usando un @dfn{firewall} +che non consente l'uso del protocollo nativo di Git, @`e possibile accedere +ugualmente al deposito usando il comando: + +@example +git clone http://git.savannah.gnu.org/r/gawk.git +@end example + +Una volta modificato il sorgente, @`e posibile usare @samp{git diff} per +produrre una @dfn{patch}, e spedirla al manutentore di @command{gawk}; si veda +@ref{Bug}, per come farlo. + +In passato era disponibile un'interfaccia Git--CVS +utilizzabile da persone che non avevano a disposizione Git. Purtroppo, +quest'interfaccia non funziona pi@`u, ma si potrebbe avere maggior fortuna usando +un sistema di controllo versioni pi@`u moderno, come Bazaar, che @`e dotato di +un'estensione Git per lavorare con depositi di sorgenti Git. + +@node Aggiungere codice +@appendixsubsec Aggiungere nuove funzionalit@`a + +@cindex @command{gawk}, aggiungere funzionalit@`a a +@cindex funzionalit@`a, aggiungere a @command{gawk} +@cindex aggiungere funzionalit@`a a @command{gawk} +Ognuno @`e libero di aggiungere tutte le nuove funzionalit@`a che vuole a +@command{gawk}. Comunque, se si desidera che tali modifiche siano incorporate +nella distribuzione di @command{gawk}, ci sono parecchi passi da fare per +rendere possibile la loro inclusione: + +@enumerate 1 +@item +Prima di inserire la nuova funzionalit@`a all'interno di @command{gawk}, +prendere in considerazione la possibilit@`a di scriverla sotto forma di +estensione (@pxref{Estensioni dinamiche}). +Se ci@`o non @`e possibile, continuare con i passi rimanenti descritti in questa +lista. + +@item +Essere disposti a firmare un documento liberatorio appropriato. +Se l'FSF deve poter distribuire le modifiche, queste vanno dichiarate +di pubblico dominio, tramite la firma di un documento apposito, oppure +attribuendo il copyright delle modifiche all'FSF. +Entrambe queste azioni sono semplici da fare, e @emph{molte} persone gi@`a +l'hanno fatto. Se ci sono domande da fare, mettersi in contatto con me +(@pxref{Bug}), +oppure @EMAIL{assign@@gnu.org,assign chiocciola gnu punto org}. + +@item +Utilizzare l'ultima versione. +@`E molto pi@`u semplice per me integrare modifiche se sono basate sull'ultima +versione disponibile di @command{gawk} o, meglio ancora, sull'ultimo codice +sorgente presente nel deposito Git. Se la versione di @command{gawk} @`e molto +vecchia, potrei non essere affatto in grado di integrare le modifiche. +(@xref{Scaricare}, +per informazioni su come ottenere l'ultima versione di @command{gawk}.) + +@item +@ifnotinfo +Seguire gli @cite{Standard di codifica GNU}. +@end ifnotinfo +@ifinfo +Si veda @inforef{Top, , Version, standards, Standard di Codifica GNU}. +@end ifinfo +Questo documento descrive come dovrebbe essere scritto il software GNU. +Se non lo si @`e letto, @`e bene farlo, preferibilmente @emph{prima} +di iniziare a modificare @command{gawk}. +(Gli @cite{Standard di codifica GNU} sono disponibili nel sito web del +@uref{http://www.gnu.org/prep/standards/, Progetto GNU}. +Sono disponibili anche versioni in formato Texinfo, Info, e DVI.) + +@cindex @command{gawk}, stile di codifica in +@item +Usare lo stile di codifica @command{gawk}. +Il codice sorgente in C di @command{gawk} segue le istruzioni dello +@cite{Standard di codifica GNU}, con qualche piccola eccezione. Il codice @`e +formattato usando lo stile tradizionale ``K&R'', in particolare per ci@`o che +riguarda il posizionamento delle parentesi graffe e l'uso del carattere TAB. +In breve, le regole di codifica per @command{gawk} +sono le seguenti: + +@itemize @value{BULLET} +@item +Usare intestazioni di funzione (prototipi) in stile ANSI/ISO quando +si definiscono delle funzioni. + +@item +Mettere il nome della funzione all'inizio della riga in cui la si sta definendo. + +@item +Usare @samp{#elif} invece di nidificare istruzioni @samp{#if} all'interno +di un'istruzione @samp{#else}. + +@item +Mettere il tipo di codice di ritorno della funzione, anche se @`e @code{int}, +sulla riga immediatamente sopra quella che contiene il nome e gli argomenti +della funzione. + +@item +Mettere degli spazi attorno alle parentesi usate nelle strutture di controllo +(@code{if}, @code{while}, @code{for}, @code{do}, @code{switch} +e @code{return}). + +@item +Non mettere spazi davanti alle parentesi usate nelle chiamate di funzione. + +@item +Mettere spazi attorno a tutti gli operatori C e dopo le virgole, +nelle chiamate di funzione. + +@item +Non usare l'operatore @dfn{virgola} per produrre degli effetti collaterali +multipli, tranne che nelle parti di inizializzazione e incremento dei cicli +@code{for}, e nel corpo delle macro. + +@item +Usare dei caratteri TAB per l'indentazione, e non dei semplici spazi. + +@item +Usare lo stile ``K&R'' per formattare le parti di programma incluse fra +parentesi graffe. + +@item +Usare confronti con @code{NULL} e @code{'\0'} per le condizioni +contenute nelle istruzioni @code{if}, @code{while} e @code{for}, e anche +nelle varie clausole @code{case} delle istruzioni @code{switch}, invece +del semplice puntatore o il semplice valore del carattere. + +@item +Usare i valori @code{true} e @code{false} per le variabili @code{booleane}, +la costante simbolica @code{NULL} per i valori dei puntatori, +e la costante carattere @code{'\0'} quando @`e il caso, invece dei valori @code{1} +e @code{0}. + +@item +Fornire un commento descrittivo di una riga per ogni funzione. + +@item +Non usare la funzione @code{alloca()} per allocare memoria dalla @dfn{stack}. +Il farlo genera dei problemi di portabilit@`a che non giustificano il vantaggio +secondario di non doversi preoccupare di liberare la memoria. Usare invece +@code{malloc()} e @code{free()}. + +@item +Non usare confronti nella forma @samp{! strcmp(a, b)} o simili. +Come disse una volta Henry Spencer, ``@code{strcmp()} non @`e una funzione +booleana!'' Usare invece @samp{strcmp(a, b) == 0}. + +@item +Per aggiungere nuovi valori a @dfn{flag} binari, usare costanti esadecimali +esplicite (@code{0x001}, @code{0x002}, @code{0x004}, etc.) invece che +spostare di un bit a sinistra in incrementi successivi +(@samp{(1<<0)}, @samp{(1<<1)}, etc.). +@end itemize + +@quotation NOTA +Qualora fossi costretto a riformattare completamente il codice per +farlo aderire allo stile di codifica usato in @command{gawk}, potrei anche +decidere di ignorare del tutto le modifiche proposte. +@end quotation + +@cindex Texinfo +@item +Aggiornare la documentazione. +Insieme col nuovo codice, fornire nuove sezioni e/o capitoli per questo +@value{DOCUMENT}. Per quanto possibile, usare il formato Texinfo, invece +di fornire soltanto del testo ASCII non formattato (sebbene un semplice testo +sia gi@`a meglio che nessuna documentazione). Le convenzioni da seguire in +@cite{@value{TITLE}} sono elencate dopo la parole chiave @samp{@@bye} alla fine +del file sorgente Texinfo. Se possibile, aggiornare anche la pagina di manuale +in formato @command{man}. + +Si dovr@`a anche firmare un documento liberatorio relativo alle +modifiche apportate alla documentazione. + +@cindex @command{git}, programma di utilit@`a +@cindex programma di utilit@`a @command{git} +@item +Inviare le modifiche come file di differenze nel formato contestuale unificato. +Usare @samp{diff -u -r -N} per confrontare i sorgenti originali dell'albero +di sorgenti @command{gawk} con la versione proposta. +Si raccomanda di usare la versione GNU di @command{diff} o, ancora meglio, +@samp{git diff} o @samp{git format-patch}. +Per inviare le modifiche proposte spedire l'output prodotto da @command{diff}. +(@xref{Bug}, per l'indirizzo di posta elettronica.) + +L'uso di questo formato rende semplice per me l'applicazione delle modifiche +alla versione principale del sorgente di @command{gawk} (usando il programma di +utilit@`a @code{patch}). Se invece tocca a me applicare le modifiche a mano, +con un editor di testo, potrei decidere di non farlo, specialmente +se le modifiche sono molte. + +@item +Includere una descrizione da aggiungere al file @file{ChangeLog} riguardo alla +modifica da voi proposta. Questo serve a minimizzare l'attivit@`a a me +richiesta, rendendo pi@`u facile per me l'accettazione delle modifiche, che +diventa pi@`u semplice se si include anche questa parte nel file di differenze +(nel formato @dfn{diff}). +@end enumerate + +Sebbene questa possa sembrare una richiesta molto esigente, si tenga presente +che, anche se il nuovo codice non @`e opera mia, tocca poi a me manutenerlo e +correggere eventuali errori. Se non @`e possibile per me farlo senza perderci +troppo tempo, potrei anche lasciar perdere la modifica. + +@node Nuovi sistemi +@appendixsubsec Portare @command{gawk} su un nuovo Sistema Operativo +@cindex portabilit@`a, @command{gawk} +@cindex sistemi operativi, portare @command{gawk} su altri + +@cindex portare @command{gawk} +Se si vuol portare @command{gawk} su di un nuovo sistema operativo, sono +necessari parecchi passi: + +@enumerate 1 +@item +Seguire le linee-guida contenute +@ifinfo +in @ref{Aggiungere codice}, +@end ifinfo +@ifnotinfo +nella precedente @value{SECTION} +@end ifnotinfo +relative allo stile di codifica, all'invio delle differenze proposte, etc. + +@item +Essere disposti a firmare un documento liberatorio appropriato. +Se l'FSF deve poter distribuire le modifiche, queste vanno dichiarate +di pubblico dominio, tramite la firma di un documento apposito, oppure +attribuendo il copyright delle modifiche all'FSF. +Entrambe queste azioni sono semplici da fare, e @emph{molte} persone gi@`a +l'hanno fatto. Se ci sono domande da fare, scrivere a me +oppure all'indirizzo @email{gnu@@gnu.org}. + +@item +Nel realizzare un @dfn{port}, tener presente che il codice +deve coesistere pacificamente con il resto di @command{gawk} e con le +versioni per altri sistemi operativi. +Evitare modifiche non necessarie alla parte di codice che @`e indipendente +dal sistema operativo. Se possibile, evitare di disseminare @samp{#ifdef}, +utili solo per il proprio @dfn{port}, all'interno del codice sorgente. + +Se le modifiche necessarie per un particolare sistema coinvolgono una parte +troppo rilevante del codice, @`e probabile che io non le accetti. +In questo caso si possono, naturalmente, distribuire le modifiche per +proprio conto, basta che si rispettino i vincoli della GPL +(@pxref{Copia}). + +@item +Un certo numero di file che fanno parte della distribuzione di @command{gawk} +sono mantenuti da terze persone e non dagli sviluppatori di @command{gawk}. +Quindi, non si dovrebbero cambiare, se non per ragioni molto +valide; vale a dire, modifiche a questi file non sono impossibili, ma +le modifiche a questi file saranno controllate con estrema attenzione. +I file sono +@file{dfa.c}, +@file{dfa.h}, +@file{getopt.c}, +@file{getopt.h}, +@file{getopt1.c}, +@file{getopt_int.h}, +@file{gettext.h}, +@file{regcomp.c}, +@file{regex.c}, +@file{regex.h}, +@file{regex_internal.c}, +@file{regex_internal.h} +e +@file{regexec.c}. + +@item +Un certo numero di altri file sono prodotti dagli Autotool [comandi di +configurazione] di GNU (Autoconf, Automake, e GNU @command{gettext}). +Neppure questi file dovrebbero essere modificati, se non per ragioni molto +valide. I file sono +@file{ABOUT-NLS}, +@file{config.guess}, +@file{config.rpath}, +@file{config.sub}, +@file{depcomp}, +@file{INSTALL}, +@file{install-sh}, +@file{missing}, +@file{mkinstalldirs}, +@file{xalloc.h} +e +@file{ylwrap}. + +@item +Essere disponibili a continuare a manutenere il @dfn{port}. +I sistemi operativi non-Unix sono supportati da volontari che tengono +aggiornato il codice necessario per compilare ed eseguire @command{gawk} +nei loro sistemi. Se nessuno @`e disponibile a tener aggiornato un @dfn{port}, +questo diventa non pi@`u supportato, e pu@`o essere necessario rimuoverlo dalla +distribuzione. + +@item +Fornire un appropriato file @file{gawkmisc.???}. +Ogni @dfn{port} ha il proprio @file{gawkmisc.???} che implementa alcune +funzioni specifiche per quel sistema operativo. Questa @`e una soluzione pi@`u +pulita, rispetto a una quantit@`a di @samp{#ifdef} sparsi nel codice. Il file +@file{gawkmisc.c} nella directory principale dei sorgenti include gli +appropriati file @file{gawkmisc.???} da ogni sottodirectory. Anche +quest'ultimo file va aggiornato. + +Ogni file @file{gawkmisc.???} del @dfn{port} ha un suffisso esplicativo +del tipo di macchina o del sistema operativo in questione---per esempio, +@file{pc/gawkmisc.pc} e @file{vms/gawkmisc.vms}. L'uso di suffissi distinti +invece di un semplice @file{gawkmisc.c}, rende possibile spostare file da +una sottodirectory propria del @dfn{port} nella sottodirectory principale, +senza cancellare incidentalmente il file @file{gawkmisc.c} vero e proprio. +(Al momento, questo rappresenta un problema solo per i @dfn{port} ai +sistemi operativi dei PC.) + +@item +Fornire un @file{Makefile} e ogni altro file sorgente o di intestazione in C +che sia necessario per il proprio sistema operativo. Tutto il codice dovrebbe +stare in una sottodirectory a parte, il cui nome sia lo stesso, o +sia indicativo, del proprio sistema operativo o del tipo di computer. +Se possibile, tentare di strutturare il codice in modo che non sia necessario +spostare file dalla propria sottodirectory nella directory principale del +codice sorgente. Se ci@`o non @`e possibile, evitare nel modo pi@`u assoluto di +usare nomi per i file che siano duplicati di nomi di file presenti nella +directory principale del codice sorgente. + +@item +Aggiornare la documentazione. +Scrivere una sezione (o pi@`u sezioni) per questo @value{DOCUMENT} +che descriva i passi di installazione e compilazione necessari per compilare +e/o installare @command{gawk} per il sistema desiderato. +@end enumerate + +Seguire queste indicazioni facilita molto l'integrazione delle +modifiche in @command{gawk} e la loro felice coesistenza con il codice di +altri sistemi operativi gi@`a presenti. + +Nel codice che viene fornito e tenuto aggiornato, si possono +tranquillamente usare uno stile di codifica e una disposizione delle +parentesi graffe di proprio gradimento. + +@node File derivati +@appendixsubsec Perch@'e i file generati sono tenuti in Git + +@cindex Git, uso per il codice sorgente di @command{gawk} +@c From emails written March 22, 2012, to the gawk developers list. + +Se si esaminano i sorgenti di @command{gawk} nel deposito Git +si noter@`a che sono inclusi file generati automaticamente dagli strumenti +dell'infrastruttura GNU, come @file{Makefile.in} generato da Automake e +anche @file{configure} proveniente da Autoconf. + +Questo comportamento @`e differente da quello di molti progetti di +Libero Software che non memorizzano i file derivati, per mantenere pi@`u +sgombro il deposito Git, rendendo cos@`{@dotless{i}} pi@`u facile comprendere quali sono le +modifiche sostanziali confrontando differenti versioni, nel tentativo di +capire cosa @`e cambiato tra una modifica e la precedente. + +Tuttavia, ci sono parecchie ragioni per le quali il manutentore di +@command{gawk} preferisce mantenere ogni cosa nel deposito Git. + +Innanzitutto, perch@'e in questo modo @`e facile generare completamente ogni +data versione, senza doversi preoccupare di avere a disposizione altri +strumenti (pi@`u vecchi, probabilmente obsoleti, e in qualche caso +perfino impossibili da trovare). + +Come esempio estremo, se solo si pensa di tentare di compilare, diciamo, la +versione Unix V7 di @command{awk}, ci si accorge che non solo @`e necessario +scaricare e ricompilare la versione V7 del comando @command{yacc} per farlo, ma +anche che serve la versione V7 del comando @command{lex}. E quest'ultima @`e +praticamente impossibile farla funzionare in un sistema GNU/Linux dei giorni +nostri.@footnote{Ci abbiamo provato. @`E stata un'esperienza dolorosa.} + +(Oppure, diciamo che la versione 1.2 di @command{gawk} richiede il comando +@command{bison} come funzionava nel 1989, e non @`e presente il file +@file{awkgram.c} [generato tramite @command{bison}] nel deposito Git. Che cosa +ci garantisce di riuscire a trovare quella versione di @command{bison}? O che +@emph{quella} riesca a generarlo?) + +Se il deposito Git comprende tutti i file derivati, +@`e facile, dopo averli scaricati, ricostruire il programma. (Oppure @`e @emph{pi@`u +facile}, a seconda di quanto si vuole risalire indietro nel tempo). + +E qui arriviamo alla seconda (e pi@`u valida) ragione per cui tutti i file +devono essere proprio nel deposito Git. Domandiamoci a chi ci si rivolge: +agli sviluppatori di @command{gawk}, oppure a un utilizzatore che intende +solo scaricare una data versione e provarla? + +Il manutentore di @command{gawk} desidera che per tutti gli utenti +@command{awk} interessati sia possibile limitarsi a clonare il deposito sul +proprio computer, selezionare la variante che lo interessa e costruirla. Senza +doversi preoccupare di avere a disposizione le versioni corrette degli Autotool +GNU.@footnote{Ecco un programma GNU che (secondo noi) @`e estremamente difficile +da estrarre dal deposito Git e compilare. Per esempio, in un vecchio (ma +ancora funzionante) PowerPC Macintosh, con il sistema operativo Mac Os X 10.5, +@`e stato necessario scaricare e compilare una tonnellata di software, +incominciando dallo stesso programma Git, per riuscire a lavorare con l'ultima +versione del codice. Non @`e un'esperienza piacevole e, specie sui vecchi +sistemi, @`e una notevole perdita di tempo. + +Neppure partire dall'ultimo archivio @command{tar} compresso @`e stata una +passeggiata: i manutentori avevano eliminato i file compressi in formato +@file{.gz} e @file{.bz2} sostituendoli con file di tipo @file{.tar.xz}. +Bisognava quindi per prima cosa scaricare e compilare @command{xz}}. +A questo serve il file @file{bootstrap.sh}. Va a "toccare" +[tramite il comando @command{touch}] vari altri file nell'ordine richiesto +in modo che + +@example +# La formula canonica per compilare il software GNU: +./bootstrap.sh && ./configure && make +@end example + +@noindent +tutto @emph{funzioni senza problemi}. + +Questo @`e estremamente importante per i rami +@code{master} e @code{gawk-@var{X}.@var{Y}-stable}. + +Inoltre, il manutentore di @command{gawk} potrebbe sostenere che +ci@`o @`e importante anche per gli sviluppatori di @command{gawk}. Tentando di +scaricare il ramo @code{xgawk}@footnote{Un ramo (non pi@`u presente) creato da +uno degli altri sviluppatori, e che non includeva i file generati.} per +compilarlo, non ci riusc@`{@dotless{i}}. (Mancava il file @file{ltmain.sh}, ed egli non +aveva idea di come crearlo, e c'erano anche ulteriori problemi.) + +La cosa lo lasci@`o in uno stato di frustrazione @emph{estrema}. Riguardo a quel +ramo, il manutentore @`e in una posizione non differente da quella di un utente +generico che voglia tentare di compilare @code{gawk-4.1-stable} o @code{master} +dal deposito Git. + +Quindi, il manutentore ritiene che sia non solo importante, ma cruciale, che +per ogni dato ramo la formula canonica evocata prima +@emph{funzioni senza problemi}. + +@c Added 9/2014: +Una terza ragione per avere tutti i file @`e che senza di essi, usare @samp{git +bisect} per tentare di trovare quale modifica ha introdotto un errore diventa +estremamente difficile. Il manutentore ha tentato di farlo su un altro +progetto che richiede di eseguire @dfn{script} di inizializzazione allo scopo +di creare lo @dfn{script} @command{configure} e cos@`{@dotless{i}} via; @`e stata un'esperienza +veramente dolorosa. Se invece il deposito Git contiene tutto il necessario, +usare @command{git bisect} al suo interno @`e molto facile. + +@c So - that's my reasoning and philosophy. + +Quali sono, quindi, alcune delle conseguenze e/o delle cose da fare? + +@enumerate 1 +@item +Non importa se ci sono file differenti nei diversi rami +prodotti da versioni differenti degli Autotool. + +@enumerate A +@item +Spetta al manutentore integrarli tra loro, e se ne occuper@`a lui. + +@item +@`E facile per lui eseguire @samp{git diff x y > /tmp/diff1 ; gvim /tmp/diff1} +per rimuovere le differenze che non sono rilevanti ai fini della revisione +del codice sorgente. +@end enumerate + +@item +Sarebbe sicuramente d'aiuto se tutti usassero le stesse versioni degli Autotool +GNU che lui usa, che in generale sono le ultime versioni rilasciate di +Automake, +Autoconf, +@command{bison} +e +GNU @command{gettext}. + +@ignore +If it would help if I sent out an ``I just upgraded to version x.y +of tool Z'' kind of message to this list, I can do that. Up until +now it hasn't been a real issue since I'm the only one who's been +dorking with the configuration machinery. +@end ignore + +@c @enumerate A +@c @item +Installare a partire dal sorgente @`e abbastanza facile. @`E il modo con cui il +manutentore ha lavorato per anni (e ancora lavora). +Egli aveva @file{/usr/local/bin} all'inizio del suo @env{PATH} e dava i +seguenti comandi: + +@example +wget http://ftp.gnu.org/gnu/@var{package}/@var{package}-@var{x}.@var{y}.@var{z}.tar.gz +tar -xpzvf @var{package}-@var{x}.@var{y}.@var{z}.tar.gz +cd @var{package}-@var{x}.@var{y}.@var{z} +./configure && make && make check +make install # come utente root +@end example + +@c @item +@ignore +These days the maintainer uses Ubuntu 12.04 which is medium current, but +he is already doing the above for Automake, Autoconf, and @command{bison}. +@end ignore + +@ignore +(C. Rant: Recent Linux versions with GNOME 3 really suck. What + are all those people thinking? Fedora 15 was such a bust it drove + me to Ubuntu, but Ubuntu 11.04 and 11.10 are totally unusable from + a UI perspective. Bleah.) +@end ignore +@c @end enumerate + +@ignore +@item +If someone still feels really strongly about all this, then perhaps they +can have two branches, one for their development with just the clean +changes, and one that is buildable (xgawk and xgawk-buildable, maybe). +Or, as I suggested in another mail, make commits in pairs, the first with +the "real" changes and the second with "everything else needed for + building". +@end ignore +@end enumerate + +La maggior parte del testo precedente fa parte di messaggi scritti +originalmente dal manutentore agli altri sviluppatori @command{gawk}. +Da uno degli sviluppatori @`e stata avanzata l'obiezione +``@dots{} che chi scarica il sorgente da Git +non @`e un utente finale''. + +Tuttavia, questo non @`e esatto. Ci sono ``utenti avanzati di @command{awk}'' +che possono installare @command{gawk} (usando la formula canonica vista sopra) +ma che non conoscono il linguaggio C. Quindi, i rami pi@`u rilevanti +dovrebbero essere sempre compilabili. + +@`E stato proposto poi di lanciare ogni notte uno @dfn{script} tramite il +programma di utilit@`a @command{cron} per creare archivi in formato @command{tar} +contenenti tutto ``il codice sorgente.'' Il problema in questo caso @`e che +ci sono differenti alberi di sorgenti, che corrispondono ai vari rami! +Quindi gli archivi notturni in questione non sono una risposta valida, anche +per il fatto che il deposito Git pu@`o rimanere senza alcuna modifica +significativa per settimane intere. + +Fortunatamente, il server Git pu@`o rispondere a questa esigenza. Per ogni +dato ramo chiamato @var{nome-ramo}, basta usare: + +@example +wget http://git.savannah.gnu.org/cgit/gawk.git/snapshot/gawk-@var{nome-ramo}.tar.gz +@end example + +@noindent +per ottenere una copia utilizzabile del ramo in questione. + +@node Future estensioni +@appendixsec Probabili estensioni future +@ignore +From emory!scalpel.netlabs.com!lwall Tue Oct 31 12:43:17 1995 +Return-Path: <emory!scalpel.netlabs.com!lwall> +Message-Id: <9510311732.AA28472@scalpel.netlabs.com> +To: arnold@skeeve.atl.ga.us (Arnold D. Robbins) +Subject: Re: May I quote you? +In-Reply-To: Your message of "Tue, 31 Oct 95 09:11:00 EST." + <m0tAHPQ-00014MC@skeeve.atl.ga.us> +Date: Tue, 31 Oct 95 09:32:46 -0800 +From: Larry Wall <emory!scalpel.netlabs.com!lwall> + +: Greetings. I am working on the release of gawk 3.0. Part of it will be a +: thoroughly updated manual. One of the sections deals with planned future +: extensions and enhancements. I have the following at the beginning +: of it: +: +: @cindex PERL +: @cindex Wall, Larry +: @display +: @i{AWK is a language similar to PERL, only considerably more elegant.} @* +: Arnold Robbins +: @sp 1 +: @i{Hey!} @* +: Larry Wall +: @end display +: +: Before I actually release this for publication, I wanted to get your +: permission to quote you. (Hopefully, in the spirit of much of GNU, the +: implied humor is visible... :-) + +I think that would be fine. + +Larry +@end ignore +@cindex Perl +@cindex Wall, Larry +@cindex Robbins, Arnold +@quotation +@i{AWK @`e un linguaggio simile a PERL, solo che @`e notevolmente pi@`u elegante.} +@author Arnold Robbins +@end quotation + +@quotation +@i{Hey!} +@author Larry Wall +@end quotation + +Il file @file{TODO} nel ramo @code{master} del deposito Git di @command{gawk} +contiene un elenco di possibili futuri miglioramenti. Alcuni di questi +riguardano il codice sorgente, e altri possibili nuove funzionalit@`a. +Consultare quel file per esaminare la lista. +@xref{Aggiunte}, +se si @`e interessati a intraprendere qualcuno dei progetti col@`a elencati. + +@node Limitazioni dell'implementazione +@appendixsec Alcune limitazioni dell'implementazione + +La tabella seguente specifica i limiti di @command{gawk} in un sistema di +tipo Unix (sebbene anche tra questi ci potrebbero essere variazioni). Altri +sistemi operativi possono avere limiti differenti. + +@multitable @columnfractions .40 .60 +@headitem Caratteristica @tab Limiti +@item Caratteri in una classe di caratteri @tab 2^(numero di bit per byte) +@item Lunghezza di un record in input @tab @code{MAX_INT} +@item Lunghezza di un record in output @tab Illimitata +@item Lunghezza di una riga di codice sorgente @tab Illimitata +@item Numero di campi in un record @tab @code{MAX_LONG} +@item Numero di ridirezioni di file @tab Illimitata +@item Numero di record in input in un singolo file @tab @code{MAX_LONG} +@item Numero totale di record in input @tab @code{MAX_LONG} +@item Numero di ridirezioni via @dfn{pipe} @tab min(numero processi per utente, numero di file aperti) +@item Valori numerici @tab Numeri a virgola mobile in doppia precisione (se non si usa la funzionalit@`a MPFR) +@item Dimensione di un campo @tab @code{MAX_INT} +@item Dimensione di una stringa letterale @tab @code{MAX_INT} +@item Dimensione di una stringa di @dfn{printf} @tab @code{MAX_INT} +@end multitable + +@node Progetto delle estensioni +@appendixsec Note di progetto dell'estensione API + +Questa @value{SECTION} documenta l'architettura dell'estensione API, +inclusa una trattazione sommaria della progettazione e dei problemi che +andavano risolti. + +La prima versione delle estensioni per @command{gawk} @`e stata sviluppata +a met@`a degli anni '90, e distribuita con la versione 3.1 di @command{gawk}, +verso la fine degli anni '90. +Il meccanismo e l'architettura sono rimasti gli stessi per quasi 15 anni, +fino al 2012. + +Il vecchio meccanismo delle estensioni usava tipi di dati e funzioni dello +stesso @command{gawk}, con un ``abile trucco'' per installare le funzioni +di estensione. + +La distribuzione @command{gawk} conteneva alcuni esempi di estensioni, solo +poche delle quali erano realmente utili. Tuttavia era chiaro fin da +principio che il meccanismo di estensione era un'aggiunta improvvisata, e +non era realmente ben concepito. + +@menu +* Problemi con le vecchie estensioni:: Problemi col vecchio meccanismo. +* Obiettivi delle estensioni:: Obiettivi del nuovo meccanismo. +* Altre scelte progettuali per le estensioni:: Qualche altra scelta progettuale. +* Futuri sviluppi delle estensioni:: Possibilit@`a di crescita futura. +@end menu + +@node Problemi con le vecchie estensioni +@appendixsubsec Problemi con le vecchie estensioni + +Il vecchio meccanismo delle estensioni presentava parecchi problemi: + +@itemize @value{BULLET} +@item +Dipendeva eccessivamente dalla struttura interna di @command{gawk}. Ogni volta +che la struttura @code{NODE}@footnote{Una struttura di dati fondamentale +all'interno di @command{gawk}.} veniva modificata, ogni estensione doveva +essere ricompilata. Inoltre, la scrittura di estensioni richiedeva una +certa familiarit@`a con le funzioni interne di @command{gawk}. Esisteva +un po' di documentazione in questo @value{DOCUMENT}, ma era ridotta al minimo. + +@item +Per poter utilizzare servizi di @command{gawk} da un'estensione era necessario +disporre di funzionalit@`a del @dfn{linker} +normalmente disponibili in ambiente di tipo Unix, ma non implementate +nei sistemi MS-Windows; chi voleva utilizzare estensioni in +MS-Windows doveva aggiungerle al modulo eseguibile di @command{gawk}, +anche se MS-Windows supporta il caricamento dinamico di oggetti condivisi. + +@item +L'API di tanto in tanto veniva modificata, in parallelo ai cambiamenti di +@command{gawk}; nessuna compatibilit@`a tra le versioni @`e stata mai prevista o +resa disponibile. +@end itemize + +Nonostante questi inconvenienti, gli sviluppatori del progetto @command{xgawk} +si basarono su @command{gawk} per sviluppare parecchie estensioni +significative. Inoltre, migliorarono le capacit@`a, in @command{gawk}, di +includere file e di accedere a oggetti condivisi. + +Una nuova API @`e rimasta un desiderio per lungo tempo, ma solo nel 2012 +il manutentore di @command{gawk} e gli sviluppatori di @command{xgawk} +iniziarono finalmente a lavorare insieme. Ulteriori informazioni riguardanti +il progetto @command{xgawk} sono forniti nella @ref{gawkextlib}. + +@node Obiettivi delle estensioni +@appendixsubsec Obiettivi per un nuovo meccanismo + +Alcuni obiettivi per la nuova API sono: + +@itemize @value{BULLET} +@item +L'API dovrebbe essere indipendente dalla struttura interna di @command{gawk}. +Le modifiche alla struttura interna di @command{gawk} dovrebbero essere +irrilevanti per chi scrive una funzione di estensione. + +@item +L'API dovrebbe consentire una compatibilit@`a @emph{binaria} [ossia a livello +di codice eseguibile, e non solo a livello di codice sorgente] tra diverse +versioni di @command{gawk}, se la stessa API rimane invariata. + +@item +L'API dovrebbe consentire che le estensioni scritte in C o C++ abbiano +all'incirca la stessa ``struttura'', per il codice awk, +di quella che hanno le funzioni di @command{awk}. Questo vuol dire che le +estensioni dovrebbero avere: + +@itemize @value{MINUS} +@item +La capacit@`a di accedere ai parametri delle funzioni. + +@item +La capacit@`a di trasformare un parametro indefinito in un vettore +(chiamata per riferimento [@dfn{by reference}]). + +@item +La capacit@`a di creare, leggere e aggiornare variabili globali. + +@item +Un accesso facile a tutti gli elementi di un vettore simultaneamente +(``appiattimento del vettore'') in modo da poter visitare tutti gli elementi +del vettore in una maniera semplice per un programma scritto in C. + +@item +La capacit@`a di creare vettori (compresi i veri "vettori di vettori" di +@command{gawk}). +@end itemize +@end itemize + +Alcuni ulteriori obiettivi rilevanti sono: + +@itemize @value{BULLET} +@item +L'API dovrebbe usare solo funzionalit@`a disponibili nella specifica ISO C 90, in +modo da consentire estensioni scritte con una vasta gamma di compilatori C e +C++. L'intestazione dovrebbe includere le appropriate direttive +@samp{#ifdef __cplusplus} e @samp{extern "C"}, in modo da poter utilizzare un +compilatore C++. (Se si usa C++, il sistema operativo in uso dev'essere in +grado di invocare dei costruttori e dei distruttori, poich@'e @command{gawk} @`e un +programma scritto in C. Al momento in cui queste note sono scritte, la cosa +non @`e stata verificata). + +@item +Il meccanismo API non dovrebbe aver bisogno di accedere ai simboli di +@command{gawk}@footnote{I @dfn{simboli} sono le variabili e le funzioni +definite all'interno di @command{gawk}. Accedere a questi simboli da parte +di codice esterno a @command{gawk} caricato dinamicamente al momento +dell'esecuzione @`e problematico in ambiente MS-Windows.} da parte del +@dfn{linker} statico, usato in fase di compilazione, o di quello dinamico, +in modo da rendere possibile la creazione di estensioni che funzionino anche +in ambiente MS-Windows. +@end itemize + +In fase di sviluppo, @`e apparso evidente che dovevano essere disponibili alle +estensioni anche altre funzionalit@`a, che sono state +successivamente implementate: + +@itemize @value{BULLET} +@item +Le estensioni dovrebbero essere in grado di agganciarsi al meccanismo di +ridirezione dell'I/O di @command{gawk}. In particolare, gli sviluppatori di +@command{xgawk} hanno programmato un cosiddetto ``gancio aperto'' (@dfn{open +hook}) per gestire autonomamente la lettura dei record. In fase di sviluppo, +questo meccanismo @`e stato generalizzato, per consentire alle estensioni di +agganciarsi sia all'elaborazione dell'input, che a quella dell'output, nonch@'e +all'I/O bidirezionale. + +@item +Un'estensione dovrebbe poter rendere disponibile una funzione di ``call back'' +(richiamo) per effettuare operazioni di pulizia all'uscita di @command{gawk}. + +@item +Un'estensione dovrebbe poter rendere disponibile una stringa di versione +cos@`{@dotless{i}} che l'opzione @option{--version} +di @command{gawk} possa informare anche sulle versioni delle estensioni. +@end itemize + +Il vincolo di evitare di accedere ai simboli di @command{gawk} pu@`o parere a +prima vista piuttosto difficile da rispettare. + +Un tipo di architettura, apparentemente usato da Perl e Ruby e forse da altri +programmi, potrebbe consistere nel mettere il codice principale di +@command{gawk} in una libreria, limitando il programma di utilit@`a +@command{gawk} a una piccola funzione @code{main()} in C che richiamerebbe +dinamicamente la libreria. + +Questo inverte i ruoli del programma principale e della sua estensione, e +complica sia la compilazione che l'installazione, trasformando la semplice +copia del programma eseguibile @command{gawk} da un sistema all'altro (o da una +posizione all'altra all'interno dello stesso sistema) in un'operazione ad alto +rischio. + +Pat Rankin ha suggerito la soluzione che @`e stata adottata. +@xref{Panoramica sul meccanismo delle estensioni}, per maggiori dettagli. + +@node Altre scelte progettuali per le estensioni +@appendixsubsec Altre scelte progettuali + +Per una scelta progettuale arbitraria, le estensioni possono accedere ai valori +delle variabili e dei vettori predefiniti (come @code{ARGV} e @code{FS}), ma +non possono modificarli, con la sola eccezione di @code{PROCINFO}. + +Il motivo di questa scelta @`e di impedire a una funzione di estensione di +alterare il flusso di un programma @command{awk} togliendogli il controllo. +Mentre una vera funzione di @command{awk} pu@`o fare quel che vuole, a +discrezione del programmatore, una funzione di estensione dovrebbe fornire un +servizio, o rendere disponibile un'API C da utilizzare all'interno di +@command{awk}, senza interferire con le variabili @code{FS} o @code{ARGC} e +@code{ARGV}. + +Inoltre, diverrebbe facile avviarsi su un sentiero scivoloso. Quante +funzionalit@`a di @command{gawk} dovrebbero essere disponibili alle estensioni? +Devono poter usare @code{getline}? Oppure richiamare @code{gsub()} o compilare +espressioni regolari? Oppure richiamare funzioni interne di @command{awk}? +(@emph{Questo} potrebbe creare molta confusione.) + +Per evitare questi problemi, gli sviluppatori di @command{gawk} hanno scelto di +iniziare con le funzionalit@`a pi@`u semplici e di base, che sono comunque +veramente utili. + +Sebbene @command{gawk} consenta cose interessanti come l'MPFR, +e vettori indicizzati internamente con numeri interi, +un'altra decisione @`e stata quella di non rendere disponibili all'API queste +funzionalit@`a, per amor di semplicit@`a e per restare fedeli alla tradizionale +semantica di @command{awk}. (In effetti, i vettori indicizzati internamente +con numeri interi sono talmente trasparenti che non sono neppure documentati!) + +In pi@`u, tutte le funzioni nell'API controllano che i puntatori ai parametri +passati loro in input non siano @code{NULL}. Se lo sono, viene emesso un +messaggio di errore. (@`E bene che il codice di estensione verifichi +che i puntatori ricevuti da @command{gawk} non siano @code{NULL}. Ci@`o non +dovrebbe succedere, ma gli sviluppatori di @command{gawk} sono solo degli +esseri umani, e capita anche a loro di commettere degli errori, di tanto in +tanto.) + +Col tempo, l'API si svilupper@`a certamente; gli sviluppatori di @command{gawk} +si aspettano che questo avvenga in base alle necessit@`a degli utenti. Per ora, +l'API disponbile sembra fornire un insieme di funzionalit@`a minimo, eppure +potente, per creare estensioni. + +@node Futuri sviluppi delle estensioni +@appendixsubsec Possibilit@`a di sviluppo futuro + +L'API pu@`o ancora essere ampliata, in due modi: + +@itemize @value{BULLET} +@item +@command{gawk} passa un ``identificativo di estensione'' all'estensione in fase +di caricamente dell'estensione. L'estensione a sua volta restituisce questo +identificativo a @command{gawk} a ogni chiamata di funzione. Questo meccanismo +consente a @command{gawk} di identificare l'estensione che lo chiama, se la +cosa dovesse risultare necessaria. + +@item +Analogamente, l'estensione passa uno ``spazio dei nomi'' a @command{gawk} +in fase di registrazione di ogni funzione estesa. Questo @`e fatto in vista di +un possibile futuro meccanismo per raggruppare funzioni di estensione, e per +evitare in questo modo possibili conflitti nei nomi di funzione. +@end itemize + +Naturalmente, al momento in cui queste righe sono state scritte, nessuna +decisione @`e stata presa riguardo ai punti sopra descritti. + +@node Meccanismo delle vecchie estensioni +@appendixsec Compatibilit@`a per le vecchie estensioni + +@iftex +Il +@end iftex +@ref{Estensioni dinamiche}, descrive le API supportate e i meccanismi +per scrivere estensioni per @command{gawk}. Quest'API @`e stata introdotta +nella @value{PVERSION} 4.1. Peraltro, gi@`a da molti anni @command{gawk} +metteva a disposizione un meccanismo di estensione che richiedeva una +familiarit@`a con la struttura interna di @command{gawk} e che non era stato +progettato altrettanto bene. + +Per garantire un periodo di transizione, @command{gawk} @value{PVERSION} 4.1 +continua a supportare il meccanismo di estensione originale. +Questo rimarr@`a disponibile per la durata di una sola versione principale. +Il supporto cesser@`a, e sar@`a rimosso dal codice sorgente, al rilascio +della prossima versione principale. + +In breve, le estensioni in stile originale dovrebbero essere compilate +includendo il file di intestazione @file{awk.h} nel codice sorgente +dell'estensione. Inoltre, va definito l'identificativo @samp{GAWK} durante la +preparazione (si usi @samp{-DGAWK} con compilatori in stile Unix). Se non lo +si fa, le definizioni in @file{gawkapi.h} risulteranno in conflitto con quelle +in @file{awk.h} e l'estensione non sar@`a compilabile. + +Come nelle versioni precedenti, un'estensione vecchio stile sar@`a caricata +usando la funzione predefinita @code{extension()} (che non viene ulteriormente +documentata). Questa funzione, a sua volta, trova e carica il file oggetto +condiviso che contiene l'estensione e chiama la sua routine C @code{dl_load()}. + +Poich@'e le estensioni in stile originale e quelle nello stile nuovo usano +differenti routine di inizializzazione(@code{dl_load()} e @code{dlload()}, +rispettivamente), esse possono tranquillamente essere installate nella stessa +directory (il cui nome deve essere contenuto nella variabile @env{AWKLIBPATH}) +senza problemi di conflitti. + +Il @dfn{team} di sviluppo di @command{gawk} raccomanda caldamente di convertire +ogni estensione del vecchio tipo ancora in uso, in modo da utilizzare la nuova +API descritta +@iftex +nel +@end iftex +@ifnottex +in +@end ifnottex +@ref{Estensioni dinamiche}. + +@node Sommario delle note +@appendixsec Sommario + +@itemize @value{BULLET} +@item +Le estensioni di @command{gawk} possono essere disabilitata sia con +l'opzione @option{--traditional} che con l'opzione @option{--posix}. +L'opzione @option{--parsedebug} @`e disponibile se @command{gawk} @`e stato +compilato con @samp{-DDEBUG}. + +@item +Il codice sorgente di @command{gawk} @`e conservato in un deposito Git +pubblicamente accessibile. Tutti possono scaricarlo e visualizzare il +codice sorgente. + +@item +I contributi a @command{gawk} sono benvenuti. Seguire le istruzioni +delineate in questo @value{CHAPTER} render@`a pi@`u agevole integrare +i contributi degli utenti nel codice principale. +Questo vale sia per il contributo di nuove funzionalit@`a che per il +@dfn{porting} a ulteriori sistemi operativi. + +@item +@command{gawk} ha alcuni limiti: generalmente quelli imposti +dall'architettura hardware della macchina. + +@item +La progettazione dell'estensione API @`e volta a risolvere alcuni problemi +riscontrati nel precedente meccanismo di estensione, ad abilitare +funzionalit@`a richieste dal progetto @code{xgawk}, e a fornire una +compatibilit@`a binaria in futuro. + +@item +Il precedente meccanismo di estensione @`e ancora supportato +nella @value{PVERSION} 4.1 +di @command{gawk}, ma sar@`a @emph{rimosso} nella prossima versione principale. + +@end itemize + + +@node Concetti fondamentali +@appendix Concetti fondamentali di programmazione +@cindex programmazione, concetti di +@cindex programmazione, concetti di + +Quest'@value{APPENDIX} si propone di definire alcuni dei concetti +e termini fondamentali usati nel resto di questo @value{DOCUMENT}. +Poich@'e questo @value{DOCUMENT} @`e dedicato ad @command{awk}, +e non riguarda la programmazione al computer in generale, la trattazione +@`e necessariamente piuttosto generica e semplificata. +(Se serve qualcosa di pi@`u approfondito, ci sono molti +altri testi introduttivi che si possono consultare.) + +@menu +* Fondamenti ad alto livello:: Una visione dall'alto. +* Fondamenti sui tipi di dati:: Una velocissima introduzione ai tipi di dati. +@end menu + +@node Fondamenti ad alto livello +@appendixsec Quel che fa un programma + +@cindex elaborazione dati +Al livello pi@`u fondamentale, il compito di un programma @`e di elaborare +alcuni dati in input e produrre dei risultati. +@ifnotdocbook +Si veda la @ref{figura-generica-flusso}. +@end ifnotdocbook +@ifdocbook +Si veda la @inlineraw{docbook, <xref linkend="figura-generica-flusso"/>}. +@end ifdocbook + +@ifnotdocbook +@float Figura,figura-generica-flusso +@caption{Flusso generico di un programma} +@ifclear SMALLPRINT +@center @image{programma-generico, , , Flusso generico di un programma} +@end ifclear +@ifset SMALLPRINT +@center @image{programma-generico, 11cm, , Flusso generico di un programma} +@end ifset +@end float +@end ifnotdocbook + +@docbook +<figure id="figura-generica-flusso" float="0"> +<title>Flusso generico di un programma</title> +<mediaobject> +<imageobject role="web"><imagedata fileref="programma-generico.png" format="PNG"/></imageobject> +</mediaobject> +</figure> +@end docbook + +@cindex programmi compilati +@cindex programmi interpretati +Il ``programma'' nella figura pu@`o essere sia un programma +compilato@footnote{I programmi compilati sono normalmente scritti +in linguaggi di programmazione di livello pi@`u basso, come C, C++, o Ada, +e quindi tradotti, o @dfn{compilati}, in una forma che +il computer pu@`o eseguire direttamente.} +(come @command{ls}), +sia un programma @dfn{interpretato}. In quest'ultimo caso, un programma +direttamente eseguibile dal computer, come @command{awk}, legge il +programma, e quindi usa le istruzioni in esso contenute per elaborare i dati. + +@cindex programmazione, passi fondamentali +Quando si scrive un programma, esso @`e composto normalmente +dai seguenti insiemi di istruzioni di base, +@ifnotdocbook +come si vede nella @ref{figura-flusso-elaborazione}: +@end ifnotdocbook +@ifdocbook +come si vede nella @inlineraw{docbook, <xref linkend="figura-flusso-elaborazione"/>}: +@end ifdocbook + +@ifnotdocbook +@float Figura,figura-flusso-elaborazione +@caption{Fasi di un programma generico} +@ifclear SMALLPRINT +@center @image{flusso-elaborazione, , , Fasi di un programma generico} +@end ifclear +@ifset SMALLPRINT +@center @image{flusso-elaborazione, 11cm , , Fasi di un programma generico} +@end ifset +@end float +@end ifnotdocbook + +@docbook +<figura id="figura-flusso-elaborazione" float="0"> +<title>Fasi di un programma generico</title> +<mediaobject> +<imageobject role="web"><imagedata fileref="flusso-elaborazione.png" format="PNG"/></imageobject> +</mediaobject> +</figure> +@end docbook + +@table @asis +@item Inizializzazione +Queste sono le cose da fare prima di iniziare la reale elaborazione dei +dati, per esempio controllare gli argomenti con cui @`e stato invocato il +programma, inizializzare dei dati di cui si potr@`a aver bisogno per la +successiva elaborazione, e cos@`{@dotless{i}} via. +Questa fase corrisponde alla regola @code{BEGIN} di @command{awk} +(@pxref{BEGIN/END}). + +Nella preparazione di una torta, questa fase corrisponde a quella di +tirar fuori tutti i contenitori in cui mischiare gli ingredienti, e la +teglia in cui cuocerla, e nell'assicurarsi di avere a disposizione tutti gli +ingredienti necessari. + +@item Elaborazione +Questa fase @`e quella in cui si svolge il lavoro vero e proprio. Il programma +legge i dati, raggruppati in ``pezzi logici'', e li elabora secondo necessit@`a. + +In quasi tutti i linguaggi di programmazione, la lettura dei dati va gestita +manualmente, controllando dopo ogni lettura se @`e +rimasto ancora qualcosa d'altro da leggere. Il paradigma @dfn{criterio di +ricerca--azione} di @command{awk} +@iftex +(@pxrefil{Per iniziare}) +@end iftex +@ifnottex +(@pxref{Per iniziare}) +@end ifnottex +gestisce automaticamente la parte di lettura dati. + +Nella preparazione di una torta, l'elaborazione corrisponde all'attivit@`a +vera e propria: rompere le uova, mescolare la farina, l'acqua e gli altri +ingredienti, e quindi mettere la torta a cuocere nel forno. + +@item Pulizia +Una volta elaborati tutti i dati, ci sono attivit@`a da svolgere prima di aver +finito. Questa fase corrisponde alla regola @code{END} di @command{awk}. +(@pxref{BEGIN/END}). + +Dopo che la torta @`e stata tirata fuori dal forno, va fatta raffreddare e +avvolta in una pellicola trasparente per evitare che qualcuno la assaggi, +e inoltre vanno lavati i contenitori e le posate. +@end table + +@cindex Algoritmi +Un @dfn{algoritmo} @`e la descrizione dettagliata della procedura necessaria per +svolgere un compito o per elaborare dati. Lo si pu@`o paragonare alla ricetta +per preparare una torta. I programmi sono il modo con cui un +algoritmo viene eseguito da un computer. +Spesso @`e compito del programmatore sia sviluppare un algoritmo, sia +programmarlo. + +@cindex record +@cindex campi +I ``pezzi logici'' nominati precedentemente sono chiamati @dfn{record} +(registrazioni), in analogia con le registrazioni del personale di una ditta, +degli studenti di una scuola, o dei pazienti di un dottore. +Ogni record @`e composto di molte parti, per esempio nome, cognome, data di +nascita, indirizzo, e cos@`{@dotless{i}} via. Le parti di cui @`e composto un record sono +chiamate @dfn{campi} del record. + +L'atto di leggere i dati @`e noto come @dfn{input}, e quello di generare +risultati @`e, come facilmente prevedibile, chiamato @dfn{output}. Spesso i due +sono riuniti sotto il nome di ``input/output'' e, ancor pi@`u spesso, con +l'abbreviazione ``I/O''. (In inglese ``input'' e ``output'' sono spesso usati +come verbi, nel gergo informatico, al posto di leggere e scrivere.) + +@cindex guidato-dai-dati, linguaggio di programmazione +@cindex linguaggio di programmazione, guidato dai dati +@command{awk} gestisce la lettura dei dati, come anche la divisione in +record e campi. Lo scopo del programma dell'utente @`e di dire ad @command{awk} +cosa fare con i dati. Questo vien fatto descrivendo @dfn{modelli} da +ricercare nei dati e @dfn{azioni} da eseguire qualora si siano trovati questi +modelli. Questa caratteristica dei programmi @command{awk}, di essere +@dfn{guidati-dai-dati}, di solito li rende pi@`u facili sia da scrivere che da +leggere. + +@node Fondamenti sui tipi di dati +@appendixsec Valore dei dati in un computer + +@cindex variabili +In un programma si tiene traccia di informazioni e valori in contenitori +chiamati @dfn{variabili}. Una variabile @`e solo un nome per designare un certo +valore, come @code{nome}, @code{cognome}, @code{indirizzo}, e cos@`{@dotless{i}} via. +@command{awk} ha molte variabili predefinite, e ha dei nomi speciali per +designare il record in input corrente e i campi che compongono il record +stesso. Si possono inoltre raggruppare molti valori associati tra di loro +sotto un unico nome, utilizzando un vettore. + +@cindex valori numerici +@cindex valori tipo stringa +@cindex valori scalari +@cindex scalari, valori +I dati, in particolare in @command{awk}, possono avere valori numerici, come 42 +o 3.1415927, o avere come valore delle stringhe. Un valore di tipo stringa @`e +essenzialmente qualsiasi cosa che non sia un numero, per esempio un nome. Le +stringhe sono talora chiamate @dfn{dati di tipo carattere}, poich@'e memorizzano +i singoli caratteri che le formano. Le singole variabili, come pure le +variabili numeriche e di tipo stringa, sono definite come valori +@dfn{scalari}. Raggruppamenti di valori, come i vettori, non sono scalari. + +@iftex +La +@end iftex +@ref{Aritmetica del computer}, ha fornito un'introduzione di base ai tipi +numerici (interi e a virgola mobile) e a come questi sono usati in un computer. +Si consiglia di rileggere quelle informazioni, comprese le numerose avvertente +l@`a esposte. + +@cindex stringhe nulle +Mentre @`e probabile che ci si sia abituati all'idea di un numero senza un valore +(cio@`e, allo zero), richiede un po' pi@`u di riflessione abituarsi all'idea di +dati di tipo carattere a lunghezza zero. Nonostante ci@`o, questo tipo di dato +esiste. @`E chiamato @dfn{stringa nulla}. La stringa nulla @`e un dato di tipo +carattere che non ha un valore. In altre parole, @`e vuoto. Si scrive cos@`{@dotless{i}} nei +programmi @command{awk}: @code{""}. + +Gli esseri umani sono abituati a usare il sistema decimale, cio@`e a base 10. +In base 10, i numeri vanno da 0 a 9, e poi ``vengono riportati'' nella +colonna successiva. (Chi si ricorda la scuola elementare? 42 = 4 x 10 + 2.) + +Ma esistono anche altre basi per i numeri. I computer normalmente usano +la base 2 o @dfn{binaria}, la base 8 o @dfn{ottale}, e la base 16 o +@dfn{esadecimale}. Nella numerazione binaria, ogni colonna rappresenta il +doppio del valore della colonna alla sua destra. Ogni colonna pu@`o contenere +solo uno 0 o un 1. Quindi, il numero binario 1010 rappresenta (1 x 8) + (0 x +4) + (1 x 2) + (0 x 1), ossia il numero decimale 10. Le numerazioni ottale ed +esadecimale sono trattate pi@`u ampiamente +@ifnottex +in +@end ifnottex +@iftex +nella +@end iftex +@ref{Numeri non-decimali}. + +Al livello pi@`u basso possibile, i computer memorizzano i valori come gruppi di +cifre binarie, o @dfn{bit}. I computer moderni raggruppano i bit in gruppi di +otto, detti @dfn{byte}. Applicazioni avanzate talora hanno necessit@`a di +manipolare i bit direttamente, e @command{gawk} @`e dotato di apposite funzioni. + +I programmi sono scritti nei linguaggi di programmazione. Esistono centinaia, +se non migliaia, di linguaggi di programmazione. Uno dei pi@`u diffusi @`e il +linguaggio di programmazione C. Il linguaggio C ha esercitato un'influsso +molto forte nella progettazione del linguaggio @command{awk}. + +@cindex Kernighan, Brian +@cindex Ritchie, Dennis +Ci sono state parecchie versioni di C. La prima @`e spesso designata come +``K&R'' C, dalle iniziali di Brian Kernighan e Dennis Ritchie, +gli autori del primo libro sul C. (Dennis Ritchie ha creato il linguaggio, +e Brian Kernighan @`e stato uno dei creatori di @command{awk}.) + +A met@`a degli anni '80 @`e iniziato uno sforzo rivolto a produrre uno +standard internazionale per il C. Questo lavoro ha raggiunto un punto di +arrivo nel 1989 con la produzione dello standard ANSI per il C. +Questo standard @`e diventato uno standard ISO nel 1990. +Nel 1999, uno standard ISO C revisionato @`e stato approvato e pubblicato. +Dove @`e opportuno, POSIX @command{awk} @`e compatible con lo standard +ISO C del 1999. + + +@node Glossario +@unnumbered Glossario + +@table @asis +@item Abbraccio mortale +La situazione in cui due processi che comunicano tra loro sono entrambi bloccati, in +attesa che l'altro processo faccia qualcosa. + +@cindex Ada, linguaggio di programmazione +@cindex linguaggio di programmazione, Ada +@item Ada +Un linguaggio di programmazione originalmente definito dal Department of +Defense U.S.A.@: per la programmazione integrata. @`E stato progettato per +favorire dei buoni metodi da seguire nell'ingegneria del software. + +@item Ambiente +Si veda ``Variabili d'ambiente''. + +@item @`Ancora +I metacaratteri @dfn{regexp} @samp{^} e @samp{$}, che richiedono che la +corrispondenza che si sta cercando si trovi all'inizio o alla fine di una +stringa, rispettivamente. + +@cindex angolo buio +@item Angolo buio +Un'area del linguaggio le cui specifiche spesso non erano (o ancora non +sono) chiare, col risultato di ottenere un comportamente inatteso o non +desiderabile. +Tali aree sono segnalate in questo @value{DOCUMENT} con +@iftex +il disegno di una torcia a margine +@end iftex +@ifnottex +``(a.b.)'' nel testo +@end ifnottex +e sono riportate nell'indice analitico sotto la voce ``angolo buio''. + +@cindex ANSI +@item ANSI +L'American National Standards Institute. Questo ente produce +parecchi standard, e tra questi gli standard per i linguaggi di +programmazione C e C++. +Questi standard spesso diventano anche internazionali. Si veda anche +``ISO''. + +@item Argomento +Un argomento pu@`o essere due cose differenti. Pu@`o essere un'opzione o un +@value{FN} passato a un comando mentre lo si invoca dalla riga dei comandi, +oppure pu@`o essere qualcosa passato a una @dfn{funzione} all'interno di un +programma, per esempio all'interno di @command{awk}. + +In quest'ultimo caso, un argomento pu@`o essere passato a una funzione in +due modi. Nel primo modo @`e passato come valore alla funzione chiamata, +ossia una copia del valore della variabile @`e reso disponibile alla funzione +chiamata, ma la variabile originale non pu@`o essere modificata dalla +funzione stessa. Nel secondo modo l'argomento @`e passato per riferimento, +ossia un puntatore alla variabile in questione @`e passato alla funzione, che +pu@`o quindi modificarla direttamente. In @command{awk} le variabili scalari +sono passate per valore, e i vettori sono passati per riferimento. +Si veda ``Passaggio per valore/riferimento''. + +@item Arrotondamento +Arrotondare il risultato di un'operazione aritmetica pu@`o essere difficile. +C'@`e pi@`u di un modo di arrotondare, e in @command{gawk} @`e possibile scegliere +quale metodo dovrebbe essere usato all'interno di un programma. +@xref{Impostare modi di arrotondare}. + +@item Assegnamento +Un'espressione @command{awk} che cambia il valore di qualche variabile o +dato oggetto di @command{awk}. Un oggetto a cui si pu@`o assegnare un valore +@`e detto un @dfn{lvalue}. I valori +assegnati sono chiamati @dfn{rvalue}. +@xref{Operatori di assegnamento}. + +@cindex Spencer, Henry +@cindex @command{sed}, programma di utilit@`a +@cindex programma di utilit@`a @command{sed} +@cindex incredibile assembler (@command{aaa}) scritto in @command{awk} +@item Assembler incredibilmente scritto in @command{awk} +Henry Spencer dell'Universit@`a di Toronto ha scritto un assembler adatto a +molti diversi hardware, usando solo @dfn{script} @command{sed} e +@command{awk}. @`E lungo migliaia di righe, e include +la descrizione dell'hardware di +numerosi micro-computer a 8 bit. @`E un +buon esempio di programma per cui sarebbe stato +meglio utilizzare un altro linguaggio. +Si pu@`o scaricare da @uref{http://awk.info/?awk100/aaa}. + +@item Asserzione +Un'istruzione in un programma che afferma che una condizione @`e verificata in +un dato punto di un programma. +Utile per ragionare su come si suppone funzioni un programma. + +@item Azione +Una serie di istruzioni @command{awk} associate a una regola. Se +l'espressione di ricerca della regola individua un record in input, +@command{awk} esegue su quel record l'azione relativa. Le azioni sono +sempre racchiuse tra parentesi graffe. +(@xref{Panoramica sulle azioni}). + +@item Bash +La versione GNU della shell standard +@ifnotinfo +(il @b{B}ourne-@b{A}gain @b{SH}ell). +@end ifnotinfo +@ifinfo +(il Bourne-Again SHell). +@end ifinfo +Si veda anche ``Bourne Shell''. + +@item Binario +Notazione a base due, che usa le cifre @code{0}--@code{1}. Poich@'e +i circuiti elettronici funzionano ``naturalmente'' in base 2 +(basta pensare a Off/On), ogni cosa all'interno di un computer @`e +calcolata usando la base 2. Ciascuna cifra rappresenta la presenza +(o l'assenza) di una potenza di 2 ed @`e chiamata un @dfn{bit}. +Cos@`{@dotless{i}}, per esempio, il numero in base due @code{10101} rappresenta il +numero in base decimale 21, ((1 x 16) + (1 x 4) + (1 x 1)). + +Poich@'e i numeri in base due diventano rapidamente molto lunghi +sia da leggere che da scrivere, normalmente li si unisce a gruppi di tre +(ossia, sono visti come numeri ottali) o a gruppi di quattro (ossia, sono +visti come numeri esadecimali). Non c'@`e un modo diretto per inserire +numeri a base due in un programma C. Se necessario, tali numeri vengono +solitamente inseriti come numeri ottali o esadecimali. +Il numero di cifre in base due contenuto nei registri usati per +rappresentare i numeri interi all'interno dei computer @`e un'indicazione +approssimativa della potenza di calcolo del computer stesso. La maggior +parte dei computer oggi usa 64 bit per rappresentare i numeri interi nei +registri di calcolo, ma registri a 32 bit, 16 bit e 8 bit sono stati +largamente in uso in passato. +@xref{Numeri non-decimali}. + +@cindex McIlroy, Doug +@cindex biscotto della fortuna +@item Biscotto della fortuna +Una particolare perla di saggezza, segno, detto o ricordo +prodotto da (o presentato a) un programma. (Con vivi ringraziamenti al Prof. +Doug McIlroy). +@ignore +From: Doug McIlroy <doug@cs.dartmouth.edu> +Date: Sat, 13 Oct 2012 19:55:25 -0400 +To: arnold@skeeve.com +Subject: Re: origin of the term "cookie"? + +I believe the term "cookie", for a more or less inscrutable +saying or crumb of information, was injected into Unix +jargon by Bob Morris, who used the word quite frequently. +It had no fixed meaning as it now does in browsers. + +The word had been around long before it was recognized in +the 8th edition glossary (earlier editions had no glossary): + +cookie a peculiar goodie, token, saying or remembrance +returned by or presented to a program. [I would say that +"returned by" would better read "produced by", and assume +responsibility for the inexactitude.] + +Doug McIlroy + +From: Doug McIlroy <doug@cs.dartmouth.edu> +Date: Sun, 14 Oct 2012 10:08:43 -0400 +To: arnold@skeeve.com +Subject: Re: origin of the term "cookie"? + +> Can I forward your email to Eric Raymond, for possible addition to the +> Jargon File? + +Sure. I might add that I don't know how "cookie" entered Morris's +vocabulary. Certainly "values of beta give rise to dom!" (see google) +was an early, if not the earliest Unix cookie. The fact that it was +found lying around on a model 37 teletype (which had Greek beta in +its type box) suggests that maybe it was seen to be like milk and +cookies laid out for Santa Claus. Morris was wont to make such +connections. + +Doug +@end ignore + +@item Bit +Abbreviazione di ``Binary Digit'' [cifra binaria]. +Tutti i valori nella memoria di un computer sono rappresentati nella forma di +cifre binarie: valori che sono zero o uno. +Gruppi di bit possono essere interpretati differentemente---come numeri +interi, numeri a virgola mobile, dati di tipo carattere, indirizzi di altri +oggetti contenuti in memoria, o altri dati ancora. +@command{awk} permette di lavorare con numeri a virgola mobile e stringhe. +@command{gawk} permette di manipolare bit con le funzioni predefinite +descritte +@ifnottex +in +@end ifnottex +@iftex +nella +@end iftex +@ref{Funzioni a livello di bit}. + +I computer sono spesso definiti dal numero di bit che usano per rappresentare +valori interi. Molti sistemi sono a 32-bit, ma i sistemi a 64-bit sono sempre +pi@`u numerosi, mentre i sistemi a 16-bit [e quelli a 8-bit] sono praticamente +scomparsi. + +@item Bourne Shell +La shell standard (@file{/bin/sh}) in Unix e nei sistemi derivati da Unix, +Originariamente scritto da Steven R.@: Bourne dei Bell Laboratories. +Molte shell (Bash, @command{ksh}, @command{pdksh}, @command{zsh}) sono +generalmente compatibili con la Bourne shell, anche quando offrono ulteriori +funzionalit@`a. + +@item C +Il linguaggio di programmazione di sistema con cui @`e scritta la maggior parte +del software GNU. Il linguaggio di programmazione @command{awk} ha una +sintassi simile a quella del C, e +questo @value{DOCUMENT} puntualizza, quando serve, le somiglianze esistenti +fra @command{awk} e C. + +In generale, @command{gawk} tenta di essere ragionevolmente simile alla +versione 1990 del C ISO. + +@item C Shell +La C Shell (@command{csh} o la sua versione migliorata @command{tcsh}) @`e una +shell Unix creata da Bill Joy verso la fine degli anni '70. La C shell si +differenzia dalla altre shell per le sue funzionalit@`a interattive, e per lo +stile complessivo, che @`e abbastanza simile a quello del linguaggio C. +La C shell non @`e compatibile all'indietro con la Bourne Shell, e per questo +motivo un'attenzione speciale @`e necessaria se si convertono alla C shell +degli script scritti per altre shell Unix, in particolare per ci@`o che +concerne la gestione delle variaili di shell. +Si veda anche ``Bourne Shell''. + +@item C++ +Un linguaggio di programmazione molto diffuso, orientato agli oggetti, +derivato dal C. + +@item Campo +Quando @command{awk} legge un record in input, suddivide il record in parti +separate da spazi vuoti (o da una @dfn{regexp} che individua il separatore, +modificabile reimpostando la variabile predefinita @code{FS}). Tali parti +sono dette campi. Se le parti sono di lunghezza fissa, si pu@`o usare la +variabile predefinita @code{FIELDWIDTHS} per descriverne le lunghezze. +Se si desidera specificare i contenuti dei campi, piuttosto che il separatore +fra i campi, si pu@`o usare la variabile predefinita @code{FPAT} per farlo. +(@xref{Separatori di campo}, +@iftex +la +@end iftex +@ref{Dimensione costante}, +e +@iftex +la +@end iftex +@ref{Separazione in base al contenuto}). + +@cindex ASCII +@cindex ISO 8859-1 +@cindex ISO Latin-1 +@cindex caratteri (codifiche macchina di caratteri) +@cindex insiemi di caratteri (codifiche macchina di caratteri) +@cindex Unicode +@item Caratteri +L'insieme di codici numerici usati da un computer per rappresentare i +caratteri (lettere, numeri, segni d'interpunzione, etc.) di un particolare +paese o localit@`a. L'insieme di caratteri pi@`u comunemente in uso oggi @`e +l'ASCII (American Standard Code for Information Interchange). Molti paesi +europei usano un'estensione dell'ASCII +nota come ISO-8859-1 (ISO Latin-1). +L'insieme di caratteri @uref{http://www.unicode.org, Unicode} sta guadagnando +popolarit@`a e affermandosi come standard, e il suo uso @`e particolarmente esteso +nei sistemi GNU/Linux. + +@cindex Kernighan, Brian +@cindex Bentley, Jon +@cindex @command{chem}, programma di utilit@`a +@cindex programma di utilit@`a @command{chem} +@item CHEM +Un preprocessore per @command{pic} che legge descrizioni di molecole +e produce l'input a @command{pic} che serve a disegnarle. +@`E stato scritto in @command{awk} +da Brian Kernighan e Jon Bentley, ed @`e disponibile in +@uref{http://netlib.org/typesetting/chem}. + +@item Classe di caratteri +Si veda ``Espressione tra parentesi quadre''. + +@cindex programmi compilati +@item Compilatore +Un programma che traduce codici sorgente scritti in qualche linguaggio +in codici eseguibili su un particolare computer. Il codice oggetto risultante +pu@`o quindi essere eseguito direttamente dal computer. +Si veda anche ``Interprete''. + +@item Concatenazione +Concatenare due stringhe significa unirle, producendo una nuova stringa. +Per esempio, la stringa @samp{pippo} concatenata con +la stringa @samp{pluto} produce la stringa @samp{pippopluto}. +(@xref{Concatenazione}). + +@item Contatore di riferimenti +Un meccanismo interno di @command{gawk} per minimizzare la quantit@`a di +memoria necessaria per contenere il valore delle variabili di tipo +stringa. Se il valore assunto da una variabile @`e usato in pi@`u di un +posto nel programma, solo una copia del valore stesso @`e tenuta in +memoria, e il contatore di riferimenti ad esso associato @`e aumentato di +uno quando lo stesso valore @`e usato da un'ulteriore variabile, e diminuito +di uno quando la variabile relativa non @`e pi@`u utilizzata. Quando il +contatore di riferimenti va a zero, la parte di memoria utilizzata per +contenere il valore della variuabile @`e liberato. + +@item Coprocesso +Un programma subordinato con il quale @`e possibile una comunicazione +bidirezionale dal programma principale. + +@item Dati oggetto +Sono costituiti da numeri e stringhe di caratteri. I numeri sono convertiti +in stringhe e viceversa, a seconda delle necessit@`a. +(@xref{Conversione}). + +@item Debugger +Un programma che serve agli sviluppatori per rimuovere ``bug'' (de-bug) dai +loro programmi. + +@item Dominio di testo +Un nome unico che identifica un'applicazione. +Usato per raggruppare messaggi che sono tradotti in fase di esecuzione +nel linguaggio locale. + +@item Doppia precisione +Una rappresentazione di numeri all'interno del computer che ha una parte +espressa sotto forma di frazione. I numeri a doppia precisione hanno pi@`u +cifre decimali che quelli a singola precisione, ma le operazioni che la +usano consumano pi@`u risorse di quelle +eseguite in singola precisione. La doppia precisione @`e il formato con cui +@command{awk} memorizza i valori numerici. Nel linguaggio C @`e il tipo di +dati detto @code{double}. + +@item Editore di flusso +Un programma che legge record da un flusso in input e li elabora uno o +pi@`u alla volta. Questo @`e diverso da quel che farebbe un programma batch +il quale potrebbe leggere completamente i file in input, prima di +iniziare a fare alcunch@'e, ed @`e diverso anche da un programma interattivo, che +richiede input dall'utente [tipicamente, una riga alla volta]. + +@item Effetto collaterale +Un effetto collaterale ha luogo quando un'espressione ha un effetto ulteriore, +invece di produrre solo un valore. Espressioni di assegnamento, +incremento e decremento, e invocazioni di funzioni hanno effetti collaterali. +(@xref{Operatori di assegnamento}). + +@cindex epoch, definizione di +@item Epoca [Inizio del tempo in Unix] +la data usata come ``inizio del tempo'' per i campi che contengono date. +I valori del tempo nella maggior parte dei dei sistemi sono rappresentati +in numero di secondi trascorsi dall'Epoca, con funzioni di libreria +che consentono di convertire tali valori nei formati normali di data e ora. + +L'Epoca nei sistemi Unix e POSIX parte dal primo gennaio 1970 alle ore +00:00:00 UTC. +Si veda anche ``GMT'' e ``UTC''. + +@item Esadecimale +Notazione per l'aritmetica in base 16, che usa le cifre @code{0}--@code{9} e +le lettere @code{A}--@code{F}, con @samp{A} +che rappresenta 10, @samp{B} che rappresenta 11, e cos@`{@dotless{i}} via, fino a +@samp{F} per 15. +I numeri esadecimali sono scritti in C prefissandoli con @samp{0x}, +per indicarne la base. Quindi, @code{0x12} @`e 18 ((1 x 16) + 2). +@xref{Numeri non-decimali}. + +@item Espressione booleana +Cos@`{@dotless{i}} detta dal nome del matematico inglese George Boole. +Si veda anche ``Espressione logica''. + +@item Espressione condizionale +Un'espressione che usa l'operatore ternario @samp{?:}, come p.es. +@samp{@var{expr1} ? @var{expr2} : @var{expr3}}. Dell'espressione +@var{expr1} viene calcolato il valore; se risulta verificata, il valore +dell'intera espressione diviene quello di @var{expr2}; altrimenti il valore @`e +quello di @var{expr3}. In ogni caso, solo una delle due espressioni +@var{expr2} e @var{expr3} +viene calcolata. (@xref{Espressioni condizionali}). + +@item Espressione di confronto +Una relazione che @`e vera o falsa, del tipo di @samp{a < b}. +Espressioni di confronto sono usate nelle istruzioni +@code{if}, @code{while}, @code{do}, @code{for} +e nelle espressioni di ricerca per scegliere quale record in input elaborare. +(@xref{Tipi di variabile e confronti}). + +@item Espressione di intervallo +Una parte di un'espressione regolare che permette di specificare +corrispondenze multiple di qualche parte della @dfn{regexp}. Le espressioni di +intervallo non erano originariamente ammesse nei programmi @command{awk}. + +@item Espressione di ricerca [@dfn{pattern}] +@itemx (detta anche "criterio di ricerca" o "modello di ricerca") +Le espressioni di ricerca individuano per @command{awk} a quali record in +input sono applicabili determinate +regole. + +Un'espressione di ricerca [pattern] @`e un'espressione condizionale specifica +che viene confrontata con ogni record +in input. Se la corrispondenza esiste, si dice che il modello @dfn{individua} +il record in input. Una tipica espressione di ricerca potrebbe confrontare +il record in input con un'espressione regolare. +(@xref{Panoramica sui criteri di ricerca}). + +@item Espressione logica +Un'espressione che usa gli operatori logici AND, OR e NOT, +scritti come @samp{&&}, @samp{||}, e @samp{!} in @command{awk}. +Spesso chiamate espressioni booleane, dal nome del matematico che per primo +ha sistematizzato questo tipo di logica matematica. + +@item Espressione regolare +un'espressione regolare (abbreviabile come ``@dfn{regexp}'') @`e un modello che +descrive un assieme di stringhe, potenzialmente illimitato. Per esempio +l'espressione regolare +@samp{R.*xp} corrisponde a qualsiasi stringa che inizia con la lettera +@samp{R} e termina con le lettere @samp{xp}. In @command{awk}, le espressioni +regolari sono usate nei modelli [pattern] e nelle espressioni condizionali. +Le espressioni regolari possono contenere sequenze di protezione. +@iftex +(@xrefil{Espressioni regolari}). +@end iftex +@ifnottex +(@xref{Espressioni regolari}). +@end ifnottex + +@item Espressione regolare calcolata +Si veda ``Espressioni regolari dinamiche''. + +@item Espressione regolare costante +Un'espressione regolare costante @`e un'espressione regolare scritta tra barre, +come @code{/pippo/}. A una tale espressione viene assegnato un valore quando +si scrive un programma @command{awk} e non pu@`o essere modificata in fase di +esecuzione del programma. (@xref{Uso di @dfn{regexp}}.) + +@item Espressione regolare dinamica +Un'espressione regolare dinamica @`e un'espressione regolare scritta come +un'espressione normale. Potrebbe essere una costante stringa, come +@code{"pippo"}, ma potrebbe anche essere un'espressione il cui valore @`e variabile +(@xref{Espressioni regolari calcolate}). + +@item Espressione tra parentesi quadre +All'interno di una @dfn{espressione regolare}, un'espressione racchiusa +fra parentesi quadre sta a indicare che un singolo carattere appartiene +a una specifica classe di caratteri. Un'espressione tra parentesi quadre +pu@`o contenere una lista di uno o pi@`u caratteri, come @samp{[abc]}, un +intervallo di caratteri, come @samp{[A-Z]}, o un nome, delimitato da +@samp{:}, che designa un insieme di caratteri conosciuto, come +@samp{[:digit:]}. La forma di espressione tra parentesi quadre +racchiusa tra @samp{:} @`e indipendente dalla rappresentazione binaria dei +caratteri stessi, che potrebbe utilizzare le codifiche ASCII, EBCDIC, o +Unicode, a seconda dell'architettura del computer, e della localizzazione. +Si veda anche ``Espressioni regolari''. + +@item Espressione tra parentesi quadre complementata +La negazione di una @dfn{espressione tra parentesi quadre}. Tutto ci@`o che +@emph{non} @`e descritto da una data espressione tra parentesi quadre. +Il simbolo @samp{^} precede l'espressione tra parentesi quadre che viene +negata. Per esempio: @samp{[[^:digit:]} +designa qualsiasi carattere che non sia una cifra. @samp{[^bad]} +designa qualsiasi carattere che non sia una delle lettere @samp{b}, @samp{a}, +o @samp{d}. +Si veda ``Espressione tra parentesi quadre''. + +@item Estensione +Una funzionalit@`a aggiunta o una modifica a un linguaggio di programmazione +o a un programma di utilit@`a, non definita dallo standard di quel linguaggio +o di quel programma di utilit@`a. +@command{gawk} ha molte estensioni rispetto al POSIX @command{awk} (fin +troppe). + +@item FDL +Free Documentation License. Si veda ``Licenza Documentazione Libera''. + +@item File speciale +Un @value{FN} interpretato internamente da @command{gawk}, invece che +gestito direttamente dal sistema operativo in cui viene eseguito +@command{gawk}---per esempio, @file{/dev/stderr}. +(@xref{File speciali}). + +@item Flag [Indicatore] +Una variabile [di tipo booleano] che, se verificata, indica la presenza o +l'assenza di qualche condizione. + +@item Formato +Le stringhe di formato controllano il modo in cui le funzioni +@code{strftime()}, @code{sprintf()} e l'istruzione @code{printf} visualizzano +l'output che producono. Inoltre, le conversioni da numeri a stringhe sono +controllate dalle stringhe di formato contenute nelle variabili predefinite +@code{CONVFMT} e @code{OFMT}. (@xref{Lettere di controllo}). + +@cindex formattatore incredibilmente duttile (@command{awf}) +@cindex programma @command{awf} (formattatore incredibilmente duttile) +@item Formattatore incredibilmente duttile (@command{awf}) +Henry Spencer all'Universit@`a di Toronto ha scritto un formattatore che +accetta un ampio sottoassieme dei comandi di formattazione @samp{nroff -ms} +e @samp{nroff -man} usando +@command{awk} e @command{sh}. +Si pu@`o scaricare da @uref{http://awk.info/?tools/awf}. + +@item Fortran +Abbreviazione di FORmula TRANslator (traduttore di formule), @`e uno dei primi +linguaggi di programmazione, pensato per il calcolo scientifico. +@`E stato ideato da John Backus ed @`e disponibile a partire dal 1957. @`E ancora +in uso ai giorni nostri. + +@cindex FSF (Free Software Foundation) +@cindex Free Software Foundation (FSF) +@cindex Stallman, Richard +@item Free Software Foundation +Un'organizzazione senza fini di lucro dedicata alla +produzione e distribuzione di software liberamente distribuibile. +@`E stata fondata da Richard M.@: Stallman, l'autore dell'originale editor +Emacs. GNU Emacs @`e la versione di Emacs maggiormente usata oggigiorno. + +@item FSF +Si veda ``Free Software Foundation''. + +@item Funzione +Una parte di un programma @command{awk} che si pu@`o chiamare da qualsiasi +punto del programma, per eseguire un compito. @command{awk} ha parecchie +funzioni predefinite. +Gli utenti possono definire essi stessi delle funzioni in qualsiasi parte +del programma. Le funzioni possono essere ricorsive, ossia possono +chiamare se stesse. +@iftex +@xrefil{Funzioni}. +@end iftex +@ifnottex +@xref{Funzioni}. +@end ifnottex +In @command{gawk} @`e anche possibile avere funzioni condivise tra diversi +programmi, incluse secondo necessit@`a usando la direttiva +@code{@@include} +(@pxref{Includere file}). +In @command{gawk} il nome della funzione da chiamare pu@`o essere generato +in fase di esecuzione, ossia in maniera dinamica. +L'estensione API di @command{gawk} fornisce funzioni di costruzione +(@pxref{Funzioni di costruzione}). + +@item Funzioni predefinite +Il linguaggio @command{awk} fornisce funzioni predefinite, che compiono +calcoli vari, di tipo numerico, di input/output e di tipo carattere. Esempi +sono @code{sqrt()} ([square root], la radice quadrata di un numero) e +@code{substr()} (che estrae una sottostringa da una stringa). +@command{gawk} fornisce funzioni per la gestione di data e ora, +le operazioni a livello di bit, l'ordinamento di +vettori, il controllo di tipo [di variabile] e la traduzione di stringhe +in fase di esecuzione di progranna. +(@xref{Funzioni predefinite}). + +@item @command{gawk} +L'implementazione GNU di @command{awk}. + +@cindex GPL (General Public License) +@cindex General Public License (GPL) +@cindex GNU General Public License +@item General Public License +Un documento che descrive le condizioni alle quali @command{gawk} e i suoi +file sorgenti possono essere distribuiti. (@xref{Copia}). + +@item GMT +``Greenwich Mean Time''. +Il termine tradizionalmente usato per UTC. +@`E la datazione usata internamente dai sistemi Unix e POSIX. +Si veda anche ``Epoca'' e ``UTC''. + +@cindex FSF (Free Software Foundation) +@cindex Free Software Foundation (FSF) +@cindex Progetto GNU +@item GNU +``GNU's not Unix'' (GNU non @`e Unix). +Un progetto della Free Software Foundation, ancora in corso, che mira a creare +un ambiente di calcolo completo, liberamente distribuibile, aderente allo +standard POSIX. + +@item GNU/Linux +Una variante del sistema GNU che usa il kernel Linux, +invece del kernel proprio della Free Software Foundation, noto come Hurd. +Il kernel Linux @`e un clone di Unix stabile, efficiente, completo di tutte le +funzionalit@`a, ed @`e stato portato su varie architetture hardware. +@`E molto diffuso su sistemi del tipo dei Personal Computer, ma funziona bene +anche in parecchi altri computer. +Il codice sorgente del kernel Linux @`e disponibile nei termini della GNU General +Public License, la qual cosa @`e forse il suo aspetto pi@`u rilevante. + +@item GPL +Si veda ``General Public License''. + +@item Graffe +I caratteri @samp{@{} e @samp{@}}. Le parentesi graffe sono usate in +@command{awk} per delimitare azioni, istruzioni composte, e il codice che +costituisce le funzioni. + +@item Guidato dai dati +Una descrizione dei programmi @command{awk}, nei quali si specifica quali sono +i dati che si vogliono elaborare, e cosa fare quando si trovano tali dati. + +@item I/O +Abbreviazione per ``Input/Output,'' ovvero il trasferimento di dati da e verso +un programma in esecuzione. + +@item Individuazione +L'azione che consiste nel confrontare una stringa con un'espressione regolare. +Se la @dfn{regexp} descrive qualcosa che @`e contenuto nella stringa, si dice che +la @dfn{individua}. + +@item Internazionalizzazione +La procedura con cui si scrive o si modifica un programma +in modo che possa inviare messaggi in lingue differenti, senza richiedere +ulteriori modifiche al codice sorgente. + +@item Intero +Un numero intero, cio@`e un numero che non ha una parte frazionaria. + +@cindex programmi interpretati +@item Interprete +Un programma che accetta come input del codice sorgente, e usa le +istruzione contenute nello stesso per elaborare dati e fornire risultati. +@command{awk} @`e tipicamente (ma non sempre) implementato come un interprete. +Si veda anche ``Compilatore''. + +@item Intervallo (nelle righe di input) +Una sequenza di righe consecutive nel/nei file in input. Un'espressione di +ricerca pu@`o specificare intervalli di righe di input da far elaborare ad +@command{awk} oppure pu@`o specificare singole righe. +(@xref{Panoramica sui criteri di ricerca}). + +@cindex ISO +@item ISO +Acronimo di International Organization for Standardization. +Questo ente elabora degli standard internazionali in vari settori, inclusi i +linguaggi di programmazione, come il C e il C++. +In ambito informatico, standard importanti come quelli per il C, C++, e POSIX +sono allo stesso tempo standard nazionali americani e standard internazionali +ISO. +In questo @value{DOCUMENT} lo Standard C @`e chiamato ``ISO C''. +Si veda @uref{http://www.iso.org/iso/home/about.htm, il sito web ISO} per +ulteriori informazioni sul nome dell'ente e sul suo acronimo di tre lettere, +che rimane lo stesso in tutte le lingue. + +@item Istruzione +Un'espressione all'interno di un programma @command{awk} nella parte +"azione" di una regola @dfn{criterio di ricerca--azione}, o all'interno +di una funzione @command{awk}. Un'espressione pu@`o essere un assegnamento +di variabile, un'operazione su un vettore, un ciclo, etc. + +@item Istruzione composta +Una serie di istruzioni @command{awk}, racchiuse tra parentesi graffe. +Le istruzioni composte possono essere nidificate [possono esserci pi@`u livelli +di parentesi graffe]. +(@xref{Istruzioni}). + +@item Istruzione di controllo +Un'istruzione di controllo @`e un'istruzione per eseguire una data operazione +o un insieme di operazioni all'interno di un programma @command{awk}, +se una determinata condizione @`e verificata. +Istruzioni di controllo sono: @code{if}, @code{for}, @code{while}, e @code{do} +(@pxref{Istruzioni}). + +@cindex Java, linguaggio di programmazione +@cindex linguaggio di programmazione, Java +@item Java +Un moderno linguaggio di programmazione originalmente sviluppato da Sun +Microsystems (ora Oracle) che prevede la programmazione orientata agli +oggetti. Sebbene normalmente sia implementato compilando le istruzioni +per una macchina virtuale standard (la JVM---Java Virtual Machine) il +linguaggio pu@`o essere compilato per essere eseguito in maniera nativa. + +@item Korn Shell +La Korn Shell (@command{ksh}) @`e una shell Unix sviluppata da David Korn, +presso i Bell Laboratories, nei primi anni '80. La Korn shell @`e +compatibile all'indietro con la Bourne shell e comprende molte funzionalit@`a +presenti nella C Shell. +Si veda anche ``Bourne Shell''. + +@item LDL +Si veda ``Licenza Documentazione Libera''. + +@cindex LGPL (Lesser General Public License) +@cindex Lesser General Public License (LGPL) +@cindex GNU Lesser General Public License +@item Lesser General Public License +Questo documento descrive i termini nei quali possono essere distribuiti +degli archivi contenenti librerie in formato eseguibile o oggetti condivisi, +e il relativo codice sorgente. + +@item LGPL +Si veda ``Lesser General Public License''. + +@item Licenza Documentazione Libera +Questo documento descrive i termini in base ai quali questo @value{DOCUMENT} +@`e pubblicato e pu@`o essere copiato. +(@xref{Licenza per Documentazione Libera GNU (FDL)}). + +@item Linguaggio @command{awk} +Il linguaggio in cui i programmi @command{awk} sono scritti. + +@item Linux +Si veda ``GNU/Linux''. + +@item Lista di caratteri +Si veda ``Espressione tra parentesi quadre''. + +@item Localizzazioni +La funzionalit@`a che fornisce i dati necessari perch@'e un programma +internazionalizzato interagisca con l'utente in un particolare linguaggio. + +@item @dfn{Lvalue} +[left-value, ossia valore a sinistra] Un'espressione che pu@`o stare alla +sinistra di un operatore di assegnamento. +Nella maggior parte dei linguaggi, gli @dfn{lvalue} possono essere variabili o +elementi di un vettore. In @command{awk}, un designatore di campo pu@`o anche +essere usato come un @dfn{lvalue}. + +@item Marcatura temporale +Un valore nel formato ``secondi a partire dall'epoch'' usato dai sistemi Unix +e POSIX. Usato per le funzioni @command{gawk} +@code{mktime()}, @code{strftime()}, e @code{systime()}. +Si veda anche ``Epoca,'' ``GMT,'' e ``UTC''. + +@item Metacaratteri +Caratteri usati all'interno di una @dfn{regexp} e che non rappresentano se +stessi. +Servono invece per rappresentare operazioni con espressioni regolari, come +per esempio delle ripetizioni, dei raggruppamenti, o delle alternanze. + +@item Nidificazione +Una nidificazione si riscontra dove l'informazione @`e organizzata a strati, +o dove degli oggetti contengono altri oggetti simili. +In @command{gawk} la direttiva @code{@@include} +pu@`o essere nidificata. La nidificazione ``naturale'' delle operazioni +aritmetiche e logiche pu@`o essere modificato attraverso l'uso di parentesi. +(@pxref{Precedenza}). + +@item No-op +Un'operazione che non fa nulla. + +@item Numero +Un dato oggetto il cui valore @`e numerico. Le implementazioni di @command{awk} +usano numeri a virgola mobile in doppia precisione per rappresentare i numeri. +Le primissime implementazioni di @command{awk} usavano numeri a virgola mobile +in singola precisione. + +@item Numero a virgola mobile +Spesso descritto, in termini matematici, come un numero ``razionale'' o reale, +@`e soltanto un numero che pu@`o avere una parte frazionaria. +Si veda anche ``Doppia precisione'' e ``Singola precisione''. + +@item Operatori di espressioni regolari +Si veda ``Metacaratteri''. + +@item Ottale +Notazione avente come base 8, nella quale le cifre sono @code{0}--@code{7}. +I numeri ottali in C sono scritti premettendo uno @samp{0}, +per indicare la base. Quindi, @code{013} @`e 11 ((1 x 8) + 3). +@xref{Numeri non-decimali}. + +@item Parentesi Graffe +Si veda ``Graffe''. + +@item Parola chiave +nel linguaggio @command{awk}, una parola chiave (keyword) @`e una parola +che ha un significato speciale. Queste parole sono riservate e non possono +essere usate come nomi di variabili. + +Le parole chiave di @command{gawk} sono: +@code{BEGIN}, +@code{BEGINFILE}, +@code{END}, +@code{ENDFILE}, +@code{break}, +@code{case}, +@code{continue}, +@code{default} +@code{delete}, +@code{do@dots{}while}, +@code{else}, +@code{exit}, +@code{for@dots{}in}, +@code{for}, +@code{function}, +@code{func}, +@code{if}, +@code{next}, +@code{nextfile}, +@code{switch}, +e +@code{while}. + +@item PEBKAC +Un acronimo inglese che descrive qual @`e probabilmente la causa pi@`u frequente +di problemi nell'uso di un computer. (@dfn{Problem Exists Between Keyboard and +Chair} [il problema si trova tra la tastiera e la sedia].) + +@item Percorso di ricerca +In @command{gawk}, una lista di directory in cui cercare file contenenti del +codice sorgente per @command{awk}. +Nella shell, una lista di directory in cui ricercare un programma eseguibile. + +@item Plug-in +Si veda ``Estensione''. + +@item POSIX +Il nome di una serie di standard che specificano l'interfaccia di un Sistema +Operativo Portabile (Portable Operating System). La ``IX'' specifica +che questi standard sono stati originati dallo Unix. +Lo standard pi@`u rilevante per gli utenti @command{awk} @`e lo +@cite{IEEE Standard for Information Technology, Standard 1003.1-2008}. +Lo standard POSIX 2008 pu@`o essere trovato in rete all'indirizzo: +@url{http://www.opengroup.org/onlinepubs/9699919799/}. + +@item Precedenza +L'ordine in cui le operazioni sono eseguite quando si usano degli operatori +se non si stabiliscono precedenze per mezzo di parentesi. + +@item Private +Variabili e/o funzioni che sono riservate all'uso esclusivo di funzioni di +libreria, e non per il programma principale @command{awk}. Un'attenzione +particolare va prestata quando si desigano tali variabili e funzioni. +(@xref{Nomi di variabili di libreria}). + +@item Programma @command{awk} +Un programma @command{awk} consiste in una serie di @dfn{espressioni di +ricerca} e @dfn{azioni}, che formano delle @dfn{regole}. Per ogni record in +input a un progranna, le regole del programma sono elaborate nell'ordine in +cui sono scritte. I programmi +@command{awk} possono anche contenere definizioni di funzioni. + +@item Record +Si veda ``Record in input'' e ``Record in output''. + +@item Record in input +Una singola parte di dati letta da @command{awk}. Solitamente, un +record in input di @command{awk} consiste in una linea di testo. +(@xref{Record}). + +@item Record in output +Un singolo pezzo di dati scritto da @command{awk}. Solitamente, un +record in output di @command{awk} consiste di una o pi@`u righe di testo. +@xref{Record}. + +@item Ricorsione +Quando una funzione chiama se stessa, direttamente o indirettamente. +Se questo @`e chiaro, si pu@`o passare a leggere la definizione successiva. +Altrimenti, si veda la voce ``Ricorsione''. + +@item @dfn{regexp} +Si veda ``Espressione regolare''. + +@item Regola +Un segmento di un programma @command{awk} che specifica come trattare singoli +record in input. Una regola consiste in una @dfn{espressione di ricerca} e in +una @dfn{azione}. +@command{awk} legge un record in input; poi, per ogni regola, se il record in +input soddisfa l'espressione di ricerca della regola, @command{awk} esegue +l'azione specificata dalla regola. +Altrimenti, la regola non ha alcun effetto su quel record in input. + +@item Ridirezione +Ridirezione significa ricevere input da quaclosa che non sia il flusso dello +standard input, o dirigere output a qualcosa di diverso dal flusso dello +standard output. + +Si pu@`o ridirigere input all'istruzione @code{getline} usando gli operatori +@samp{<}, @samp{|}, e @samp{|&}. +Si pu@`o ridirigere l'output delle istruzioni @code{print} e @code{printf} verso +un file o un comando di sistema, usando gli operatori @samp{>}, @samp{>>}, +@samp{|}, e @samp{|&}. +(@xref{Getline}, +e @ref{Ridirezione}). + +@item @dfn{Rvalue} +[right-value, ossia valore a destra] Un valore che pu@`o apparire alla destra +di un operatore di assegnazione. +In @command{awk}, essenzialmente ogni espressione ha un valore. +Ognuno di questi valori @`e un @dfn{rvalue}. + +@item Scalare +Un valore singolo, sia numerico che di tipo stringa. +Le variabili normali sono scalari; i vettori e le funzioni non lo sono. + +@item Scorciatoia +La natura degli operatori logici @command{awk} @samp{&&} e @samp{||}. +Se il valore dell'intera espressione in cui sono contenuti @`e determinabile +valutando solo una parte iniziale dell'espressione, la parte seguente non @`e +presa in considerazione. +(@xref{Operatori booleani}). + +@item @dfn{Script} @command{awk} +Un altro nome per designare un programma @command{awk}. + +@item @command{sed} +Si veda ``Editore di flusso''. + +@item Seme +Il valore iniziale, o il punto di partenza, di una sequenza di numeri casuali. + +@item Sequenze di protezione +Una speciale sequenza di caratteri usata per descrivere caratteri non +stampabili, come @samp{\n} (ritorno a capo) o @samp{\033} per il carattere +ASCII ESC (Escape). (@xref{Sequenze di protezione}). + +@item Shell +Il programma che interpreta i comandi nei sistemi Unix e in quelli che +rispettano lo standard POSIX. +La shell funziona sia interattivamente che come un linguaggio di +programmazione, che elabora file sequenziali, detti @dfn{script} di shell. + +@item Singola precisione +Una rappresentazione di numeri all'interno del computer che ha una parte +espressa sotto forma di frazione. I numeri a singola precisione hanno meno +cifre significative di quelli a doppia precisione, ma le operazioni relative +richiedono talora meno risorse elaborative da parte del computer. +Questo tipo di numero @`e quello usato da alcune tra le prime versioni di +@command{awk} per memorizzare valori numerici. Nel linguaggio C, sono numeri +di tipo @code{float}. + +@item Spazio +Il carattere generato premendo la barra spaziatrice sulla tastiera. + +@item Spazio vuoto +Una sequenza di spazi, TAB, o caratteri di ritorno a capo presenti in un +record in input o in una stringa. + +@item Stringa +Un dato che consiste in una sequenza di caratteri, come @samp{Io sono una +stringa}. Le costanti stringa sono scritte tra doppi apici nel linguaggio +@command{awk} e possono contenere sequenze di protezione +(@xref{Sequenze di protezione}). + +@item Stringa nulla +Una stringa che non contiene alcun carattere. @`E rappresentabile +esplicitamente nei programmi @command{awk} mettendo due caratteri di +doppio apice uno dietro all'altro (@code{""}). La si pu@`o inserire nei dati +in input mettendo due separatori di campo uno dietro all'altro. + +@item Stringa vuota +Si veda ``Stringa nulla''. + +@item Tab +Il carattere generato premendo il tasto @kbd{TAB} sulla tastiera. +Normalmente pu@`o generare sino a otto spazi in output. + +@cindex Linux +@cindex GNU/Linux +@cindex Unix +@cindex sistemi operativi basati su BSD +@cindex NetBSD +@cindex FreeBSD +@cindex OpenBSD +@item Unix +Un sistema operativo per computer originalmente sviluppato nei primi anni '70 +presso gli AT&T Bell Laboratories. Inizialmente si diffuse nelle universit@`a +di tutto il mondo e in seguito si estese agli ambienti del mondo del lavoro +come un sistema per lo sviluppo del software e come server di rete. +Ci sono parecchie versioni di Unix a pagamento, come pure parecchi sistemi +operativi modellati su Unix e il cui codice sorgente @`e liberamente +disponibile. (come GNU/Linux, @uref{http://www.netbsd.org, NetBSD}, +@uref{http://www.freebsd.org, FreeBSD}, e +@uref{http://www.openbsd.org, OpenBSD}). + +@item UTC +L'abbreviazione comune per ``Universal Coordinated Time'' (tempo coordinato +universale). Questa @`e l'ora standard di Greenwich, (UK), usata come tempo +di riferimento per i calcoli relativi a marcature temporali. +Si veda anche ``Epoca'' e ``GMT''. + +@item Variabile +Un nome per designare un valore. In @command{awk}, le variabili possono +essere degli scalari o dei vettori. + +@item Variabili d'ambiente +Una collezione di stringhe, in formato @samp{@var{nome}=@var{valore}}, che +ogni programma ha a disposizione. Gli utenti in generale assegnano valori +alle variabili d'ambiente per fornire informazioni a vari programmi. +Esempi tipici sono le variabili d'ambiente @env{HOME} e @env{PATH}. + +@item Variabili predefinite +@code{ARGC}, +@code{ARGV}, +@code{CONVFMT}, +@code{ENVIRON}, +@code{FILENAME}, +@code{FNR}, +@code{FS}, +@code{NF}, +@code{NR}, +@code{OFMT}, +@code{OFS}, +@code{ORS}, +@code{RLENGTH}, +@code{RSTART}, +@code{RS}, +e +@code{SUBSEP} +sono le variabili con un significato speciale in @command{awk}. +In pi@`u, +@code{ARGIND}, +@code{BINMODE}, +@code{ERRNO}, +@code{FIELDWIDTHS}, +@code{FPAT}, +@code{IGNORECASE}, +@code{LINT}, +@code{PROCINFO}, +@code{RT}, +e +@code{TEXTDOMAIN} +sono le variabili con un significato speciale in @command{gawk}. +Se i loro valori sono modificati, il contesto di esecuzione di @command{awk} +cambia. +(@xref{Variabili predefinite}). + +@item Vettore +Un raggruppamento di molti valori con uno stesso nome. +La maggior parte dei linguaggi fornisce solo vettori sequenziali. +@command{awk} fornisce vettori associativi. + +@item Vettore associativo +Un vettore i cui indici possono essere numeri o stringhe, e non solamente +interi sequenziali compresi in un intervallo prestabilito. + +@end table + +@end ifclear + +@c The GNU General Public License. + +@node Copia +@unnumbered Licenza Pubblica Generale GNU (GPL) +@ifnotdocbook +@center Versione 3, 29 Giugno 2007 +@end ifnotdocbook +@docbook +<subtitle>Versione 3, 29 Giugno 2007</subtitle> +@end docbook + +@c This file is intended to be included within another document, +@c hence no sectioning command or @node. + +@display +Copyright @copyright{} 2007 Free Software Foundation, Inc. @url{http://fsf.org/} + +This is an unofficial translation of the GNU General Public License into +Italian. It was not published by the Free Software Foundation, and does not +legally state the distribution terms for software that uses the GNU GPL—only +the original English text of the GNU GPL does that. However, we hope that this +translation will help Italian speakers understand the GNU GPL better. + +Questa @`e una traduzione non ufficiale in italiano della GNU General Public +License. Questa traduzione non @`e stata pubblicata dalla Free Software +Foundation, e non stabilisce i termini legali di distribuzione del software +che usa la GNU GPL. Soltanto la versione originale in inglese della GNU GPL +fa ci@`o. Ciononostante, speriamo che questa traduzione possa aiutare gli utenti +di lingua italiana a comprendere un po' meglio la GNU GPL. + +A chiunque @`e permesso copiare e ridistribuire copie esatte di questo documento +di licenza, ma non @`e in alcun modo consentito apportarvi modifiche. +@end display + +@c fakenode --- for prepinfo +@heading Preambolo + +La GNU General Public License @`e una licenza libera e basata su copyleft per +software e altri tipi di opere. + +Le licenze della maggior parte del software e di altre opere materiali sono +pensate per togliere la libert@`a di condividere e modificare tali opere. Al +contrario, la GNU General Public License ha l'obiettivo di garantire la +libert@`a di condividere e modificare tutte le versioni di un programma e di +fare in modo che esso rimanga software libero per tutti gli utenti. Noi, Free +Software Foundation, usiamo la GNU General Public License per la maggior parte +del nostro software; essa viene applicata anche a qualunque altro software +rilasciato dall'autore sotto questa licenza. Chiunque pu@`o utilizzare questa +licenza per i suoi programmi. + +Quando parliamo di software libero (free software), ci riferiamo al concetto +di libert@`a, non al prezzo. Le nostre General Public License sono progettate +per garantire che chiunque abbia la libert@`a di distribuire copie di software +libero (anche dietro pagamento di un prezzo, se lo desidera), che chiunque +riceva o possa ricevere il codice sorgente se lo vuole, che chiunque possa +apportare modifiche al software o utilizzarne delle porzioni in altri software +liberi, e che chiunque sappia che ha il diritto di fare tutte queste cose col +software libero. + +Per proteggere i vostri diritti, abbiamo la necessit@`a di impedire che altri vi +neghino questi diritti o vi obblighino a rinunciarvi. Pertanto, chiunque +distribuisce o modifica software rilasciato con questa licenza assume dei +precisi doveri: il dovere di rispettare la libert@`a degli altri. + +Per esempio, chi distribuisce copie di un programma rilasciato sotto questa +licenza, sia gratis che dietro pagamento di un prezzo, e' obbligato a +riconoscere a chi riceve il software esattamente gli stessi diritti che ha +ricevuto. Deve garantire che chi riceva il software abbia o possa avere +accesso al codice sorgente. E deve chiaramente far conoscere ai destinatari +del software queste condizioni, cos@`{@dotless{i}} che essi conoscano quali sono i loro +diritti. + +Gli sviluppatori che usano la GNU GPL proteggono i vostri diritti in due modi: +(1) Rivendicando il copyright sul software, e (2) offrendovi questa licenza +che vi garantisce il diritto legale di copiarlo e/o di modificarlo. + +Al fine di proteggere gli sviluppatori e gli autori, la GPL spiega chiaramente +che non c'@`e nessuna garanzia per questo software libero. Nell'interesse degli +utenti e degli autori, la GPL impone che le versioni modificate del software +vengano esplicitamente marcate come ``modificate'', in maniera tale che +eventuali problemi non vengano erroneamente attribuiti agli autori delle +versioni precedenti. + +Alcuni dispositivi sono progettati per negare agli utenti l'installazione o +l'esecuzione di versioni modificate del software che gira sugli stessi, anche +se il costruttore si riserva la possibilit@`a di farlo. Ci@`o @`e fondamentalmente +incompatibile con l'obiettivo di garantire la libert@`a degli utenti di +modificare il software. Una ripetizione sistematica di tali abusi avviene nel +campo dei dispositivi per usi individuali, e ci@`o rende questi abusi ancora pi@`u +inaccettabili. Pertanto, abbiamo realizzato questa versione della GPL al fine +di proibire queste pratiche. Se problemi simili dovessero sorgere in altri +ambiti, saremo pronti ad estendere queste misure a questi nuovi ambiti in +versioni future della GPL, nella maniera che si render@`a necessaria per +difendere la libert@`a degli utenti. + +In conclusione, tutti i programmi sono costantemente minacciati dai brevetti +sul software. Gli Stati non dovrebbero permettere ai brevetti sul software di +limitare lo sviluppo e l'utilizzo di software per computer, ma nei Paesi in +cui ci@`o avviene noi vogliamo evitare in particolare il pericolo che i brevetti +sul software applicati ad un programma libero possano renderlo, a tutti gli +effetti, proprietario. Per impedire ci@`o, la GPL assicura che non @`e possibile +utilizzare i brevetti sul software per rendere un programma non libero. + +I termini e le condizioni esatte per la copia, la distribuzione e la modifica +del software sono riportate di seguito. + +@c fakenode --- for prepinfo +@heading TERMINI E CONDIZIONI + +@enumerate 0 +@item Definizioni + +``Questa Licenza'' si riferisce alla versione 3 della GNU General Public +License. + +``Copyright'' indica anche leggi simili al copyright che riguardano altri tipi +di opere, come le maschere per la produzione di semiconduttori. + +``Il Programma'' indica qualunque opera che sia soggetta a copyright e che sia +rilasciata sotto questa Licenza. I detentori della licenza sono indicati come +``tu'' o ``voi''. Licenziatari e destinatari possono essere individui o +organizzazioni. + +``Modificare'' un'opera significa copiare o adattare tutta o parte dell'opera in +una maniera che richieda un permesso di copyright, e non indica la semplice +azione di fare una esatta copia dell'opera. L'opera risultante viene chiamata +``versione modificata'' dell'opera precedente, oppure viene detta opera ``basata +sulla'' opera precedente. + +Una ``opera coperta da questa licenza'' indica il Programma originale non +modificato oppure un'opera basata sul Programma. + +``Propagare'' un'opera significa fare qualunque cosa con essa che, in mancanza +di un esplicito permesso, ti renda direttamente o indirettamente perseguibile +per violazione secondo le vigenti normative sul copyright, ad eccezione della +semplice esecuzione del Programma su un computer o della modifica di una copia +privata. La Propagazione include la copia, la distribuzione (con o senza +modifiche), la messa a disposizione al pubblico e, in alcuni stati, altre +attivit@`a simili e connesse. + +``Distribuire'' un'opera indica qualunque forma di propagazione che permetta a +terze parti di effettuare o ricevere delle copie. La mera interazione con un +utente attraverso una rete di computer, senza che ci sia alcun trasferimento +di una copia, non @`e considerata ``Distribuzione''. + +Una interfaccia utente interattiva fornisce delle ``Adeguate Informazioni +Legali'' soltanto nel caso in cui include una apposita funzionalit@`a, resa +adeguatamente visibile, che (1) visualizzi un'adeguata informazione di +copyright, e (2) informi l'utente che non c'@`e alcuna garanzia sull'opera +(eccetto nel caso in cui delle garanzie sono espressamente fornite), dica che +il licenziatario pu@`o distribuire l'opera utilizzando questa Licenza, indichi +come @`e possibile prendere visione di una copia di questa Licenza. Se +l'interfaccia presenta una lista di comandi o di opzioni, come per esempio un +men@`u, una delle opzioni fornite nella lista deve rispettare questa condizione. + +@item Codice Sorgente + +Il ``codice sorgente'' di un'opera indica la forma pi@`u indicata dell'opera per +effettuare modifiche su di essa. Il ``codice oggetto'' indica qualunque forma +dell'opera che non sia codice sorgente. + +Una ``Interfaccia Standard'' @`e una interfaccia che risponde ad uno standard +ufficiale definito da un ente di standardizzazione riconosciuto o, nel caso di +interfacce specifiche per un particolare linguaggio di programmazione, una +interfaccia che @`e largamente utilizzata dagli sviluppatori per sviluppare in +tale linguaggio. + +Le ``Librerie di Sistema'' di un eseguibile includono qualsiasi cosa, eccetto +l'opera nel suo insieme, che (a) sia inclusa nella normale forma di +pacchettizzazione di un ``Componente Principale'', ma che non @`e parte di quel +Componente Principale, e (b) che serva solo a consentire l'uso dell'opera con +quel Componente Principale, o per implementare una Interfaccia Standard per la +quale esista una implementazione disponibile al pubblico in forma sorgente. Un +``Componente Principale'', in questo contesto, @`e un componente essenziale +(kernel, gestore di finestre eccetera) dello specifico sistema operativo +(ammesso che ce ne sia uno) sul quale l'eseguibile esegue, o un compilatore +utilizzato per produrre il programma, o un interprete di codice oggetto +utilizzato per eseguire il programma. + +Il ``Sorgente Corrispondente'' per un'opera in forma di codice oggetto @`e il +codice sorgente necessario per generare, installare e (per un programma +eseguibile) eseguire il codice oggetto e per modificare l'opera, inclusi gli +script per controllare le suddette attivit@`a di generazione, installazione ed +esecuzione. Non sono incluse le Librerie di Sistema usate dal programma, o gli +strumenti di utilit@`a generica o i programmi liberamente accessibili che sono +utilizzati, senza modifiche, per portare a termine le suddette attivit@`a ma che +non fanno parte dell'opera. Per esempio, il sorgente corrispondente include i +file con le definizioni delle interfacce associati ai file sorgente +dell'opera, e il codice sorgente delle librerie condivise e sottoprogrammi +collegati dinamicamente specificatamente necessari per il programma, ad +esempio a causa di stretta comunicazione dati o di controllo di flusso tra +questi sottoprogrammi e altre parti del programma. + +Il Sorgente Corrispondente non include qualunque cosa che l'utente possa +rigenerare automaticamente da altre parti del Sorgente Corrispondente stesso. + +Il Sorgente Corrispondente di un'opera in forma di codice sorgente @`e l'opera +stessa. + +@item Principali Diritti + +Tutti i diritti garantiti da questa Licenza sono garantiti per la durata del +copyright sul Programma, e sono irrevocabili ammesso che le suddette +condizioni siano rispettate. Questa Licenza afferma esplicitamente il tuo +permesso illimitato di eseguire il Programma non modificato. Il risultato +dell'esecuzione di un programma coperto da questa Licenza @`e a sua volta +coperto da questa Licenza solo se il risultato stesso, a causa del suo +contenuto, @`e un'opera coperta da questa Licenza. Questa Licenza riconosce il +tuo diritto all'uso legittimo o altri diritti equivalenti, come stabilito +dalla legislazione sul copyright. + +Puoi creare, eseguire e propagare programmi coperti da questa Licenza che tu +non distribuisci, senza alcuna condizione fino a quando la tua Licenza rimane +valida. Puoi distribuire opere coperte da questa Licenza ad altri al solo +scopo di ottenere che essi facciano delle modifiche al programma +esclusivamente per te, o che ti forniscano dei servizi per l'esecuzione di +queste opere, ammesso che tu rispetti i termini di questa Licenza nel +distribuire tutto il materiale per il quale non detieni il copyright. Coloro i +quali creano o eseguono per conto tuo un programma coperto da questa Licenza +lo fanno esclusivamente in tua vece, sotto la tua direzione e il tuo +controllo, in maniera tale che sia proibito a costoro effettuare copie di +materiale di cui detieni il copyright al di fuori della relazione che +intrattengono nei tuoi confronti. + +Distribuire opere coperte da licenza in qualunque altra circostanza @`e +consentito soltanto alle condizioni espresse in seguito. Non @`e consentito +sottolicenziare le opere: la sezione 10 lo rende non necessario. + +@item Protezione dei diritti legali degli utenti dalle leggi anti-elusione + +Nessun programma protetto da questa Licenza pu@`o essere considerato parte di +una misura tecnologica di restrizione che sottosta ad alcuna delle leggi che +soddisfano l'articolo 11 del ``WIPO copyright treaty'' adottato il 20 Dicembre +1996, o a simili leggi che proibiscono o limitano l'elusione di tali misure +tecnologiche di restrizione. + +Quando distribuisci un programma coperto da questa Licenza, rifiuti tutti i +poteri legali atti a proibire l'elusione di misure tecnologiche di restrizione +ammesso che tale elusione sia effettuata nell'esercizio dei diritti garantiti +da questa Licenza riguardo al programma coperto da questa Licenza, e rinunci +all'intenzione di limitare l'operativit@`a o la modifica del programma per far +valere, contro i diritti degli utenti del programma, diritti legali tuoi o di +terze parti che impediscano l'elusione di misure tecnologiche di restrizione. + +@item Distribuzione di Copie Esatte + +Ti @`e permesso distribuire copie esatte del codice sorgente del Programma come +lo hai ricevuto, con qualunque mezzo, ammesso che tu aggiunga in maniera +appropriata su ciascuna copia una appropriata nota di copyright; che tu lasci +intatti tutti gli avvisi che affermano che questa Licenza e tutte le clausole +non-permissive aggiunte in accordo con la sezione 7 sono valide per il codice +che distribuisci; che tu lasci intatti tutti gli avvisi circa l'assenza di +garanzia; che tu fornisca a tutti i destinatari una copia di questa Licenza +assieme al Programma. + +Puoi richiedere il pagamento di un prezzo o di nessun prezzo per ciascuna +copia che distribuisci, e puoi offrire supporto o garanzia a pagamento. + +@item Distribuzione di Versioni modificate del sorgente + +Puoi distribuire un'opera basata sul Programma, o le modifiche per produrla a +partire dal Programma, nella forma di codice sorgente secondo i termini della +sezione 4, ammesso che tu rispetti anche tutte le seguenti condizioni: + +@enumerate a +@item +L'opera deve recare con s@`e delle informazioni adeguate che affermino che tu +l'hai modificata, indicando la data di modifica. + +@item +L'opera deve recare informazioni adeguate che affermino che essa @`e rilasciata +sotto questa Licenza e sotto le condizioni aggiuntive secondo quanto indicato +dalla Sezione 7. Questa condizione modifica la condizione espressa alla +sezione 4 di ``lasciare intatti tutti gli avvisi''. + +@item +Devi rilasciare l'intera opera, nel suo complesso, sotto questa Licenza a +chiunque venga in possesso di una copia di essa. Questa Licenza sar@`a pertanto +applicata, assieme ad eventuali clausole aggiunte in osservanza della Sezione +7, all'opera nel suo complesso, a tutte le sue parti, indipendentemente da +come esse siano pacchettizzate. Questa Licenza nega il permesso di licenziare +l'opera in qualunque altro modo, ma non rende nullo un tale permesso ammesso +che tu lo abbia ricevuto separatamente. + +@item +Se l'opera ha delle interfacce utente interattive, ciascuna deve mostrare +delle Adeguate Informazioni Legali; altrimenti, se il Programma ha delle +interfacce interattive che non visualizzano delle Adeguate Informazioni +Legali, il tuo programma non @`e obbligato a visualizzarle. +@end enumerate + +La giustapposizione di un'opera coperta da questa Licenza assieme ad altre +opere separate e indipendenti, che non sono per loro natura estensioni del +Programma, e che non sono combinate con esso a formare un altro programma pi@`u +grande, dentro o in uno stesso supporto di memorizzazione a lungo termine o di +distribuzione, @`e semplicemente detto ``aggregato'' se la raccolta e il suo +copyright non sono utilizzati per limitare l'accesso o i diritti legali degli +utenti della raccolta stessa oltre ci@`o che ciascun singolo programma consente. +L'inclusione di un programma coperto da questa Licenza in un aggregato non +comporta l'applicazione di questa Licenza alle altre parti dell'aggregato. + +@item Distribuzione in formato non-sorgente + +Puoi distribuire un programma coperto da questa Licenza in formato di codice +oggetto secondo i termini delle sezioni 4 e 5, ammesso che tu fornisca anche +il Sorgente Corrispondente in formato comprensibile da un computer sotto i +termini di questa stessa Licenza, in uno dei seguenti modi: + +@enumerate a +@item +Distribuendo il codice oggetto in, o contenuto in, un prodotto fisico (inclusi +i mezzi fisici di distribuzione), accompagnato dal Sorgente Corrispondente su +un supporto fisico duraturo comunemente utilizzato per lo scambio di software. + +@item +Distribuendo il codice oggetto in, o contenuto in, un prodotto fisico (inclusi +i mezzi fisici di distribuzione), accompagnato da un'offerta scritta, valida +per almeno tre anni e valida per tutto il tempo durante il quale tu offri +ricambi o supporto per quel modello di prodotto, di fornire a chiunque +possieda il codice oggetto (1) una copia del Sorgente Corrispondente di tutto +il software contenuto nel prodotto che @`e coperto da questa Licenza, su un +supporto fisico duraturo comunemente utilizzato per lo scambio di software, ad +un prezzo non superiore al costo ragionevole per effettuare fisicamente tale +distribuzione del sorgente, oppure (2) accesso alla copia del Sorgente +Corrispondente attraverso un server di rete senza alcun costo aggiuntivo. + +@item +Distribuendo copie singole del codice oggetto assieme ad una copia +dell'offerta scritta di fornire il Sorgente Corrispondente. Questa possibilit@`a +@`e permessa soltanto occasionalmente e per fini non commerciali, e solo se tu +hai ricevuto il codice oggetto assieme ad una tale offerta, in accordo alla +sezione 6b. + +@item +Distribuendo il codice oggetto mediante accesso da un luogo designato (gratis +o dietro pagamento di un prezzo), e offrendo un accesso equivalente al +Sorgente Corrispondente alla stessa maniera a partire dallo stesso luogo senza +costi aggiuntivi. Non devi obbligare i destinatari a copiare il Sorgente +Corrispondente assieme al codice oggetto. Se il luogo dal quale copiare il +codice oggetto @`e un server di rete, il Sorgente Corrispondente pu@`o trovarsi su +un server differente (gestito da te o da terze parti) che fornisca +funzionalit@`a equivalenti per la copia, a patto che tu fornisca delle +indicazioni chiare accanto al codice oggetto che indichino dove trovare il +Sorgente Corrispondente. Indipendentemente da quale server ospiti il Sorgente +Corrispondente, tu rimani obbligato ad assicurare che esso rimanga disponibile +per tutto il tempo necessario a soddisfare queste condizioni. + +@item +Distribuendo il codice oggetto mediante trasmissione peer-to-peer, a patto che +tu informi gli altri peer circa il luogo in cui il codice oggetto e il +Sorgente Corrispondente sono gratuitamente offerti al pubblico secondo i +termini della sezione 6d. + +@end enumerate + +Una porzione separabile del codice oggetto, il cui sorgente @`e escluso dal +Sorgente Corrispondente e trattato come Libreria di Sistema, non deve essere +obbligatoriamente inclusa nella distribuzione del codice oggetto del +programma. + +Un ``Prodotto Utente'' @`e un (1) ``prodotto consumer'', cio@`e qualunque propriet@`a +personale tangibile che @`e normalmente utilizzata per scopi personali, +familiari o domestici, oppure (2) qualunque cosa progettata o venduta per +essere utilizzata in ambiente domestico. Nella classificazione di un prodotto +come ``prodotto consumer'', i casi dubbi andranno risolti in favore dell'ambito +di applicazione. Per un dato prodotto ricevuto da un dato utente, ``normalmente +utilizzato'' si riferisce ad un uso tipico o comune di quella classe di +prodotti, indipendentemente dallo stato dell'utente specifico o dal modo in +cui l'utente specifico utilizza, o si aspetta o ci si aspetta che utilizzi, il +prodotto. Un prodotto @`e un ``prodotto consumer'' indipendentemente dal fatto che +abbia usi commerciali, industriali o diversi da quelli ``consumer'', a meno che +questi usi non rappresentino il solo modo utile di utilizzare il prodotto in +questione. + +Le ``Informazioni di Installazione'' per un Prodotto Utente sono i metodi, le +procedure, le chiavi di autorizzazioni o altre informazioni necessarie per +installare ed eseguire versioni modificate di un programma coperto da questa +Licenza all'interno di un Prodotto Utente, a partire da versioni modificate +dei suoi Sorgenti Corrispondenti. Tali informazioni devono essere sufficienti +ad assicurare che il funzionamento del codice oggetto modificato non sia in +nessun caso proibito o ostacolato per il solo fatto che sono state apportate +delle modifiche. + +Se distribuisci un codice oggetto secondo le condizioni di questa sezione in, +o assieme, o specificatamente per l'uso in o con un Prodotto Utente, e la +distribuzione avviene come parte di una transazione nella quale il diritto di +possesso e di uso del Prodotto Utente viene trasferito al destinatario per +sempre o per un periodo prefissato (indipendentemente da come la transazione +sia caratterizzata), il Sorgente Corrispondente distribuito secondo le +condizioni di questa sezione deve essere accompagnato dalle Informazioni di +Installazione. Questa condizione non @`e richiesta se n@`e tu n@`e una terza parte +ha la possibilit@`a di installare versioni modificate del codice oggetto sul +Prodotto Utente (per esempio, se il programma @`e installato su una ROM) + +La condizione che richiede di fornire delle Informazioni di Installazione non +implica che venga fornito supporto, garanzia o aggiornamenti per un programma +che @`e stato modificato o installato dal destinatario, o per il Prodotto Utente +in cui esso @`e stato modificato o installato. L'accesso ad una rete pu@`o essere +negato se le modifiche apportate impattano materialmente sull'operativit@`a +della rete o se violano le regole e i protocolli di comunicazione attraverso +la rete. + +Il Sorgente Corrispondente distribuito, e le Informazioni di Installazione +fornite, in accordo con questa sezione, devono essere in un formato che sia +pubblicamente documentato (e con una implementazione pubblicamente disponibile +in formato di codice sorgente), e non devono richiedere speciali password o +chiavi per essere spacchettate, lette o copiate. + +@item Condizioni Aggiuntive + +Le ``Condizioni Aggiuntive'' sono condizioni che completano le condizioni di +questa Licenza permettendo delle eccezioni a una o pi@`u delle condizioni sopra +elencate. Le condizioni aggiuntive che sono applicabili all'intero Programma +devono essere considerate come se fossero incluse in questa Licenza, a patto +che esse siano valide secondo le normative vigenti. Se alcune condizioni +aggiuntive fanno riferimento soltanto ad alcune parti del Programma, quelle +parti possono essere utilizzate separatamente sotto le stesse condizioni, ma +l'intero Programma rimane sottoposto a questa Licenza senza riferimento ad +alcuna condizione aggiuntiva. + +Quando distribuisci una copia di un programma coperto da questa Licenza, puoi, +a tua discrezione, eliminare qualunque condizione aggiuntiva dalla copia, o da +parte di essa. (Le Condizioni Aggiuntive possono essere scritte in maniera +tale da richiedere la loro rimozione in certi casi di modifica del Programma). +Puoi aggiungere Condizioni Aggiuntive su materiale, aggiunto da te ad un'opera +coperta da questa Licenza, per il quale hai o puoi garantire un'adeguata +licenza di copyright. + +Indipendentemente da qualunque altra condizione di questa Licenza, e per il +materiale che aggiungi ad un'opera coperta da questa Licenza, puoi (se +autorizzato dai legittimi detentori del copyright per il suddetto materiale) +aggiungere alle condizioni di questa Licenza delle condizioni che: + +@enumerate a +@item +Negano la garanzia o limitano la responsabilit@`a del Programma in maniera +differente da quanto riportato nelle sezioni 15 e 16 di questa Licenza; oppure + +@item +Richiedono il mantenimento di specifiche e circostanziate informative legali o +di note di attribuzione ad autori nel materiale o assieme alle Adeguate +Informazioni Legali mostrate dal Programma che lo contiene; oppure + +@item +Proibiscono di fornire informazioni errate o ingannevoli sull'origine e la +provenienza del materiale in oggetto, o richiedono che versioni modificate di +tale materiale siano appositamente marcate in maniera differente rispetto alla +versione originale; oppure + +@item +Limitano l'utilizzo per scopi pubblicitari del nome dei detentori del +copyright o degli autori del materiale; oppure + +@item +Rifiutano di garantire diritti secondo le leggi sulla propriet@`a intellettuale +circa l'uso di nomi, marchi di fabbrica o similari; oppure + +@item +Richiedono l'indennizzo dei detentori del copyright o degli autori del +materiale in oggetto da parte di chi distribuisce il materiale (o versioni +modificate dello stesso) con impegni contrattuali circa la responsabilit@`a nei +confronti del destinatario, per qualunque responsabilit@`a che questi impegni +contrattuali dovessero imporre direttamente ai suddetti detentori del +copyright e autori. +@end enumerate + +Tutte le altre condizioni addizionali non-permissive sono considerate +``ulteriori restrizioni'', secondo il significato specificato alla sezione 10. +Se il Programma o parti di esso contengono, all'atto della ricezione dello +stesso, informative che specificano che esso @`e soggetto a questa Licenza +assieme ad una condizione che @`e una ``ulteriore restrizione'', puoi rimuovere +quest'ultima condizione. Se un documento di licenza contiene ulteriori +restrizioni ma permette di rilicenziare o distribuire il Programma con questa +Licenza, puoi aggiungere al Programma del materiale coperto dalle condizioni +di quel documento di licenza, a patto che le ulteriori restrizioni non +compaiano nelle versioni rilicenziate o ridistribuite. + +Se aggiungi ad un Programma coperto da questa Licenza delle condizioni +aggiuntive in accordo con questa sezione, devi aggiungere anche, nei file +sorgenti corrispondenti, un avviso che riassuma le condizioni aggiuntive +applicate a quei file, ovvero un avviso che specifichi dove @`e possibile +trovare copia delle condizioni aggiunte. + +Tutte le Condizioni aggiuntive, permissive o non-permissive, devono essere +espresse nella forma di una licenza scritta e separata, o espresse +esplicitamente come eccezioni; in entrambi i casi valgono le condizioni +succitate. + +@item Cessazione di Licenza + +Non puoi propagare o modificare un programma coperto da questa Licenza in +maniera diversa da quanto espressamente consentito da questa Licenza. +Qualunque tentativo di propagare o modificare altrimenti il Programma @`e nullo, +e provoca l'immediata cessazione dei diritti garantiti da questa Licenza +(compresi tutte le eventuali licenze di brevetto garantite ai sensi del terzo +paragrafo della sezione 11). + +In ogni caso, se cessano tutte le violazioni di questa Licenza, allora la tua +licenza da parte di un dato detentore del copyright viene ripristinata (a) in +via cautelativa, a meno che e fino a quando il detentore del copyright non +cessa esplicitamente e definitivamente la tua licenza, e (b) in via permanente +se il detentore del copyright non ti notifica in alcun modo la violazione +entro 60 giorni dalla cessazione della licenza. + +Inoltre, la tua licenza da parte di un dato detentore del copyright viene +ripristinata in maniera permanente se il detentore del copyright ti notifica +la violazione in maniera adeguata, se questa @`e la prima volta che ricevi una +notifica di violazione di questa Licenza (per qualunque Programma) dallo +stesso detentore di copyright, e se rimedi alla violazione entro 30 giorni +dalla data di ricezione della notifica di violazione. + +La cessazione dei tuoi diritti come specificato in questa sezione non provoca +la cessazione delle licenze di terze parti che abbiano ricevuto copie o +diritti da te secondo questa Licenza. Se i tuoi diritti cessano e non sono +ristabiliti in via permanente, non hai diritto di ricevere nuove licenze per +lo stesso materiale, secondo quanto stabilito nella sezione 10. + +@item L'ottenimento di copie non richiede l'accettazione della Licenza + +Non sei obbligato ad accettare i termini di questa Licenza al solo fine di +ottenere o eseguire una copia del Programma. Similmente, propagazioni +collaterali di un Programma coperto da questa Licenza che occorrono come +semplice conseguenza dell'utilizzo di trasmissioni peer-to-peer per la +ricezione di una copia non richiedono l'accettazione della Licenza. In ogni +caso, solo e soltanto questa Licenza ti garantiscono il permesso di propagare +e modificare qualunque programma coperto da questa Licenza. Queste azioni +violano le leggi sul copyright nel caso in cui tu non accetti questa Licenza. +Pertanto, modificando o propagando un programma coperto da questa Licenza, +indichi implicitamente la tua accettazione della Licenza. + +@item Licenza Automatica per i successivi destinatari + +Ogni qual volta distribuisci un programma coperto da questa Licenza, il +destinatario riceve automaticamente una licenza, dal detentore originario del +copyright, di eseguire, modificare e propagare il programma, nel rispetto di +questa Licenza. Non sei ritenuto responsabile del rispetto di questa Licenza +da parte di terze parti. + +Una ``transazione d'entit@`a'' @`e una transazione che trasferisce il controllo di +una organizzazione, o sostanzialmente di tutti i suoi beni, che suddivide una +organizzazione o che fonde pi@`u organizzazioni. Se la propagazione di un +programma coperto da questa Licenza @`e conseguente ad una transazione di +entit@`a, ciascuna parte che ha ruolo nella transazione e che riceve una copia +del programma riceve allo stesso tempo qualsiasi licenza sul programma che i +predecessori della parte possedevano o potevano rilasciare nel rispetto del +paragrafo precedente, e in pi@`u il diritto di possesso del Sorgente +Corrispondente del programma dal predecessore in interesse, se il predecessore +lo possiede o se pu@`o ottenerlo senza troppe difficolt@`a. + +Non puoi imporre nessuna ulteriore restrizione sull'esercizio dei diritti +garantiti o affermati da questa Licenza. Per esempio, non puoi imporre un +prezzo di licenza, una royalty, o altri costi per l'esercizio dei diritti +garantiti da questa Licenza, a non puoi dar corso ad una controversia (ivi +incluse le controversie incrociate o la difesa in cause legali) affermando che +siano stati violati dei brevetti a causa della produzione, dell'uso, della +vendita, della messa in vendita o dell'importazione del Programma o di sue +parti. + +@item Brevetti + +Un ``contribuente'' @`e un detentore di copyright che autorizza l'uso secondo +questa Licenza di un Programma o di un'opera basata sul Programma. L'opera +cos@`{@dotless{i}} licenziata viene chiamata ``versione del contribuente''. + +I ``diritti essenziali di brevetto'' da parte di un contribuente sono tutti i +diritti di brevetto che appartengono o che sono controllati dal contribuente, +che siano gi@`a acquisiti o che saranno acquisiti in futuro, che possano essere +violati in qualche maniera, consentita da questa Licenza, generando, +modificando o vendendo la versione del contribuente, ma non includono i +diritti che possano essere violati soltanto come conseguenza di ulteriori +modifiche alla versione del contribuente. In relazione a questa definizione, +il termine ``controllo'' include il diritto di garantire sottolicenze di +brevetto in maniera consistente con le condizioni di questa Licenza. + +Ciascun contribuente ti garantisce la licenza di brevetto sui diritti +essenziali di brevetto del contribuente stesso non-esclusiva, valida in tutto +il mondo, esente da royalty, di creare, usare, vendere, offrire in vendita, +importare e altrimenti eseguire, modificare e propagare i contenuti della +versione del contribuente. + +Nei tre paragrafi successivi, con ``licenza di brevetto'' si intende qualunque +accordo o contratto, comunque denominato, di non rivendicazione di un brevetto +(come per esempio un permesso esplicito di utilizzare un brevetto o un accordo +di rinuncia alla persecuzione per violazione di brevetto). ``Garantire'' una +tale licenza di brevetto ad una parte significa portare a termine un tale +accordo o contratto di non rivendicazione di brevetto contro la parte. + +Se distribuisci un programma coperto da questa Licenza, confidando +consapevolmente su una licenza di brevetto, e il Sorgente Corrispondente per +il programma non @`e reso disponibile per la copia, senza alcun onere aggiuntivo +e comunque nel rispetto delle condizioni di questa Licenza, attraverso un +server di rete pubblicamente accessibile o tramite altri mezzi facilmente +accessibili, allora devi (1) fare in modo che il Sorgente Corrispondente sia +reso disponibile come sopra, oppure (2) fare in modo di rinunciare ai benefici +della licenza di brevetto per quel particolare programma, oppure (3) +adoperarti, in maniera consistente con le condizioni di questa Licenza, per +estendere la licenza di brevetto a tutti i destinatari successivi. ``Confidare +consapevolmente'' significa che tu sei attualmente cosciente che, eccettuata la +licenza di brevetto, la distribuzione da parte tua di un programma protetto da +questa Licenza in un paese, o l'utilizzo in un paese del programma coperto da +questa Licenza da parte di un destinatario, pu@`o violare uno o pi@`u brevetti in +quel paese che tu hai ragione di ritenere validi. + +Se, come conseguenza o in connessione con una singola transazione o con un +dato accordo, distribuisci, o fai in modo di distribuire, un programma coperto +da questa Licenza, e garantisci una licenza di brevetto per alcune delle parti +che ricevono il Programma autorizzandole ad utilizzare, propagare, modificare +o distribuire una specifica copia del Programma, allora la licenza di brevetto +che fornisci @`e automaticamente estesa a tutti i destinatari del Programma +coperto da questa Licenza e delle opere basate sul Programma. + +Una licenza di brevetto @`e ``discriminatoria'' se non include nell'ambito della +sua copertura, proibisce l'esercizio, o @`e vincolata al non-esercizio di uno o +pi@`u dei diritti che sono specificatamente garantiti da questa Licenza. Non +puoi distribuire un Programma coperto da questa Licenza se sei parte di un +accordo con una terza parte la cui attivit@`a comprende la distribuzione di +software, secondo il quale tu sei costretto ad un pagamento alla parte terza +in funzione della tua attivit@`a di distribuzione del Programma, e in +conseguenza del quale la parte terza garantisce, a qualunque delle parti che +riceveranno il Programma da te, una licenza di brevetto discriminatoria (a) +assieme a copie del Programma coperto da questa Licenza distribuite da te (o +ad altre copie fatte da codeste copie), oppure (b) principalmente per e in +connessione con specifici prodotti o raccolte di prodotti che contengono il +Programma, a meno che l'accordo non sia stato stipulato, o le licenze di +brevetto non siano state rilasciate, prima del 28 Marzo 2007. + +Nessuna parte di questa Licenza pu@`o essere interpretata come atta ad escludere +o limitare gli effetti di qualunque altra licenza o altri meccanismi di difesa +dalla violazione che possano altrimenti essere resi disponibili dalla +normativa vigente in materia di brevetti. + +@item Nessuna resa di libert@`a altrui + +Se ti vengono imposte delle condizioni (da un ordine giudiziario, da un +accordo o da qualunque altra eventualit@`a) che contraddicono le condizioni di +questa Licenza, non sei in nessun modo esonerato dal rispetto delle condizioni +di questa Licenza. Se non puoi distribuire un Programma coperto da questa +Licenza per sottostare simultaneamente agli obblighi derivanti da questa +Licenza e ad altri obblighi pertinenti, allora non puoi distribuire il +Programma per nessun motivo. Per esempio, se accetti delle condizioni che ti +obbligano a richiedere il pagamento di una royalty per le distribuzioni +successivamente effettuate da coloro ai quali hai distribuito il Programma, +l'unico modo per soddisfare sia queste condizioni che questa Licenza @`e evitare +del tutto la distribuzione del Programma. + +@item Utilizzo con la GNU Affero General Public License + +Indipendentemente da qualunque altra condizione espressa da questa Licenza, +hai il permesso di collegare o combinare qualunque Programma coperto da questa +Licenza con un'opera rilasciata sotto la versione 3 della licenza GNU Affero +General Public License, ottenendo un singolo Programma derivato, e di +distribuire il Programma risultante. Le condizioni di questa Licenza +continuano a valere per le parti riguardanti il Programma che sono coperte da +questa Licenza, mentre le condizioni speciali della GNU Affero General Public +License, sezione 13, riguardanti l'interazione mediante rete, saranno +applicate al Programma cos@`{@dotless{i}} risultante. + +@item Versioni rivedute di questa Licenza + +La Free Software Foundation pu@`o pubblicare delle versioni rivedute e/o delle +nuove versioni della GNU General Public License di tanto in tanto. Tali +versioni saranno simili, nello spirito, alla presente versione, ma potranno +differire nei dettagli al fine di affrontare nuovi problemi e nuove +situazioni. + +A ciascuna versione viene assegnato un numero identificativo di versione. Se +il Programma specifica che si applica a s@`e stesso una certa versione della GNU +General Public License, ``o qualunque altra versione successiva'', hai la +possibilit@`a di sottostare alle condizioni di quella specifica versione o di +qualunque altra versione successiva pubblicata dalla Free Software Foundation. +Se il Programma non specifica un numero di versione della GNU General Public +License, puoi scegliere qualunque versione della GNU General Public License +pubblicata dalla Free Software Foundation. + +Se il Programma specifica che un sostituto o un procuratore pu@`o decidere quali +versioni future della GNU General Public License posso essere utilizzate, +allora tale scelta di accettazione di una data versione ti autorizza, in +maniera permanente, ad utilizzare quella versione della Licenza per il +Programma. + +Versioni successive della Licenza possono garantire diritti aggiuntivi o +leggermente differenti. Ad ogni modo, nessun obbligo aggiuntivo viene imposto +agli autori o ai detentori di copyright come conseguenza della tua scelta di +adottare una versione successiva della Licenza. + +@item Rinuncia alla Garanzia + +NON C'@`E NESSUNA GARANZIA PER IL PROGRAMMA, PER QUANTO CONSENTITO DALLE +VIGENTI NORMATIVE. ECCETTO QUANDO ALTRIMENTI STABILITO PER ISCRITTO, I +DETENTORI DEL COPYRIGHT E/O LE ALTRE PARTI FORNISCONO IL PROGRAMMA ``COS@`I COME +@`E'' SENZA GARANZIA DI ALCUN TIPO, N@'E ESPRESSA N@'E IMPLICITA, INCLUSE, MA NON +LIMITATE A, LE GARANZIE DI COMMERCIABILIT@`A O DI UTILIZZABILIT@`A PER UN +PARTICOLARE SCOPO. L'INTERO RISCHIO CONCERNENTE LA QUALIT@`A E LE PRESTAZIONI +DEL PROGRAMMA @`E DEL LICENZIATARIO. SE IL PROGRAMMA DOVESSE RISULTARE +DIFETTOSO, IL LICENZIATARIO SI ASSUME I COSTI DI MANUTENZIONE, RIPARAZIONE O +CORREZIONE. + +@item Limitazione di Responsabilit@`a + +IN NESSUN CASO, A MENO CHE NON SIA RICHIESTO DALLA NORMATIVA VIGENTE O +CONCORDATO PER ISCRITTO, I DETENTORI DEL COPYRIGHT, O QUALUNQUE ALTRA PARTE +CHE MODIICA E/O DISTRIBUISCE IL PROGRAMMA SECONDO LE CONDIZIONI PRECEDENTI, +POSSONO ESSERE RITENUTI RESPONSABILI NEI CONFRONTI DEL LICENZIATARIO PER +DANNI, INCLUSO QUALUNQUE DANNEGGIAMENTO GENERICO, SPECIALE, INCIDENTALE O +CONSEQUENZIALE DOVUTO ALL'USO O ALL'IMPOSSIBILIT@`A D'USO DEL PROGRAMMA +(INCLUSI, MA NON LIMITATI A, LE PERDITE DI DATI, LA CORRUZIONE DI DATI, LE +PERDITE SOSTENUTE DAL LICENZIATARIO O DA TERZE PARTI O L'IMPOSSIBILIT@`A DEL +PROGRAMMA A FUNZIONARE ASSIEME AD ALTRI PROGRAMMI), ANCHE NEL CASO IN CUI IL +DETENTORE O LE ALTRE PARTI SIANO STATI AVVISATI CIRCA LA POSSIBILIT@`A DI TALI +DANNEGGIAMENTI. + +@item Interpretazione delle Sezioni 15 e 16 + +Se la dichiarazione di garanzia e la limitazione di responsabilit@`a fornite +precedentemente non hanno effetto legale in un paese a causa delle loro +condizioni, le corti di giustizia devono applicare la norma locale che pi@`u si +avvicini al rifiuto assoluto di qualsivoglia responsabilit@`a civile relativa al +Programma, a meno che una garanzia o una assunzione di responsabilit@`a scritta +non accompagni una copia del programma ottenuta dietro pagamento. +@end enumerate + +@c fakenode --- for prepinfo +@heading FINE DEI TERMINI E DELLE CONDIZIONI + +@c fakenode --- for prepinfo +@heading Come applicare queste condizioni di Licenza ai vostri programmi + +Se sviluppi un nuovo programma, e vuoi che esso sia della massima utilit@`a, il +modo migliore @`e renderlo software libero in modo che chiunque possa +ridistribuirlo e modificarlo secondo i termini di questa Licenza. + +Per fare ci@`o, allega le seguenti note informative al programma. Il modo +migliore @`e inserirle all'inizio di ciascun file sorgente, al fine di rimarcare +adeguatamente la mancanza di garanzia; ciascun file dovrebbe inoltre contenere +la dichiarazione di copyright e un riferimento al posto in cui @`e possibile +ottenere la versione completa delle note informative. + +@smallexample +@var{<una riga con nome del programma e breve descrizione di ci@`o che fa.>} +Copyright (C) @var{<anno>} @var{<nome dell'autore>} + +Questo software @`e libero; lo puoi distribuire e/o modificare alle condizioni +stabilite nella 'GNU General Public License' pubblicata dalla Free Software +Foundation; fai riferimento alla versione 3 della Licenza, o (a tua scelta) +a una qualsiasi versione successiva. + +Questo programma @`e distribuito con la speranza che sia utile, ma SENZA +ALCUNA GARANZIA; senza neppure la garanzia implicita di COMMERCIABILIT@`A o +IDONEIT@`A AD UN PARTICOLARE SCOPO. Si veda la 'GNU General Public License' per +ulteriori dettagli. + +Dovresti aver ricevuto una copia della GNU General Public License assieme a +questo programma; se non @`e cos@`{@dotless{i}}, si veda +@url{http://www.gnu.org/licenses/}. +@end smallexample + +Inoltre, aggiungi le informazioni necessarie a contattarti via posta ordinaria +o via posta elettronica. + +Se il programma interagisce mediante terminale, fai in modo che visualizzi, +quando viene avviato in modalit@`a interattiva, un breve messaggio come quello +che segue: + +@smallexample +@var{<programma>} Copyright (C) @var{<anno>} @var{<nome dell'autore>} +Questo programma non ha ALCUNA GARANZIA; per dettagli usare il comando +@samp{show w}. +Questo @`e software libero, e ognuno @`e libero di ridistribuirlo +sotto certe condizioni; usare il comando @samp{show c} per i dettagli. +@end smallexample + +Gli ipotetici comandi @samp{show w} e @samp{show c} devono visualizzare le parti +corrispondenti della GNU General Public License. Naturalmente i comandi del +tuo programma potrebbero essere differenti; per una interfaccia di tipo GUI, +dovresti usare un bottone ``About'' o ``Info''. + +Devi inoltre fare in modo che il tuo datore di lavoro (se lavori come +programmatore presso terzi) o la tua scuola, eventualmente, firmino una +``rinuncia al copyright'' sul programma, se necessario. Per maggiori +informazioni su questo punto, e su come applicare e rispettare la GNU GPL, +consultare la pagina @url{http://www.gnu.org/licenses/}. + +La GNU General Public License non consente di incorporare il programma +all'interno di software proprietario. Se il tuo programma @`e una libreria di +funzioni, potresti ritenere pi@`u opportuno consentire il collegamento tra +software proprietario e la tua libreria. Se @`e questo ci@`o che vuoi, allora +utilizza la GNU Lesser General Public License anzich@'e questa Licenza, ma prima +leggi @url{http://www.gnu.org/philosophy/why-not-lgpl.html}. + +@ifclear FOR_PRINT +@c The GNU Free Documentation License. +@node Licenza per Documentazione Libera GNU (FDL) +@unnumbered Licenza per Documentazione Libera GNU (FDL) +@ifnotdocbook +@center Versione 1.3, 3 Novembre 2008 +@end ifnotdocbook + +@docbook +<subtitle>Versione 1.3, 3 Novembre 2008 </subtitle> +@end docbook + +@cindex FDL (Free Documentation License) +@cindex Free Documentation License (FDL) +@cindex GNU Free Documentation License + +@c This file is intended to be included within another document, +@c hence no sectioning command or @node. + +@display +Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. +@uref{http://fsf.org} + +This is an unofficial translation of the GNU Free Documentation License into +Italian. It was not published by the Free Software Foundation, and does not +legally state the distribution terms for software that uses the GNU FDL—only +the original English text of the GNU FDL does that. However, we hope that this +translation will help Italian speakers understand the GNU FDL better. + +Questa @`e una traduzione non ufficiale della GNU Free Documentation License +in italiano. Non @`e una pubblicazione della Free Software Foundation, e non +ha validit@`a legale per i termini di distribuzione della documentazione che +usa la GNU FDL; solo il testo originale inglese della GNU FDL ha tale +validit@`a. Comunque, speriamo che questa traduzione aiuti chi parla +italiano a comprendere meglio la GNU FDL. + +A chiunque @`e permesso copiare e ridistribuire copie esatte di questo documento +di licenza, ma non @`e in alcun modo consentito apportarvi modifiche. + +@end display + +@enumerate 0 +@item +PREAMBOLO + +Lo scopo di questa licenza @`e di rendere @dfn{liberi} un manuale, un testo o +altri documenti funzionali e utili, nel senso di assicurare a tutti la +libert@`a effettiva di copiarli e ridistribuirli, con o senza modifiche, con +o senza fini di lucro. In secondo luogo questa licenza prevede per autori +ed editori il modo per ottenere il giusto riconoscimento del proprio +lavoro, preservandoli dall'essere considerati responsabili per modifiche +apportate da altri. + +Questa licenza garantisce il ``copyleft'': questo significa che i lavori che +derivano dal documento originale devono essere ugualmente liberi. @`E il +complemento alla Licenza Pubblica Generale GNU, che @`e una licenza di tipo +``copyleft'' pensata per il software libero. + +Questa licenza @`e stata progettata appositamente per l'uso con manuali di +software libero, perch@'e il software libero ha bisogno di documentazione +libera: un programma libero dovrebbe accompagnarsi a manuali che +forniscano le stesse libert@`a del software. Questa licenza non @`e limitata +alla manualistica del software; pu@`o essere utilizzata per ogni testo che +tratti un qualsiasi argomento e al di l@`a dell'avvenuta pubblicazione +cartacea. Si raccomanda l'uso di questa licenza principalmente per opere +che abbiano fini didattici o per manuali. + +@item +APPLICABILIT@`A E DEFINIZIONI + +Questa licenza si applica a qualsiasi manuale o altra opera, su ogni tipo +di supporto, che contenga la nota, posta dal detentore del copyright, che +attesti la possibilit@`a di distribuzione secondo i termini di questa +licenza. Tale nota permette universalmente, senza pagamento di diritti e +senza limiti di durata di utilizzare il lavoro secondo le condizioni qui +specificate. Con ``documento'', nel seguito ci si riferisce a qualsiasi +manuale o opera. Ogni fruitore @`e un destinatario della licenza ed @`e ad +esso che si fa riferimento. Si conviene che la licenza viene accettata se +si copia, modifica o distribuisce il lavoro in una maniera tale da +richiedere il permesso secondo le leggi sul copyright. + +Una ``versione modificata'' del documento @`e ogni opera contenente il +documento stesso o parte di esso, sia riprodotto alla lettera che con +modifiche, oppure traduzioni in un'altra lingua. + +Una ``sezione secondaria'' @`e un'appendice cui si fa riferimento o una +premessa del documento e riguarda esclusivamente il rapporto dell'editore +o dell'autore del documento con l'argomento generale del documento stesso +(o argomenti affini) e non contiene nulla che possa essere compreso +nell'argomento principale. (Perci@`o, se il documento @`e in parte un manuale +di matematica, una sezione secondaria non pu@`o contenere spiegazioni di +matematica). Il rapporto con l'argomento pu@`o essere un tema collegato +storicamente con il soggetto principale o con soggetti affini, o essere +costituito da argomentazioni legali, commerciali, filosofiche, etiche o +politiche pertinenti. + +Le ``sezioni non modificabili'' sono alcune sezioni secondarie i cui titoli +sono esplicitamente elencati come titoli delle sezioni non modificabili +nella nota che indica che il documento @`e realizzato sotto questa licenza. +Se una sezione non rientra nella precedente definizione di sezione +secondaria, allora non @`e permesso che venga definita come non +modificabile. Il documento pu@`o anche non contenere sezioni non +modificabili. Se nel documento non vengono indicate sezioni non +modificabili, allora significa che non ve ne sono. + +I ``testi di copertina'' sono dei brevi brani di testo che sono elencati, +nella prima o quarta pagina di copertina, nella nota che indica che il +documento @`e rilasciato sotto questa licenza. Il testo sulla prima di +copertina pu@`o essere composto al massimo di 5 parole mentre quello sulla +quarta di copertina pu@`o essere al massimo di 25 parole. + +Una copia ``trasparente'' indica una copia leggibile da un calcolatore, +codificata in un formato le cui specifiche sono disponibili pubblicamente, +tale che il suo contenuto possa essere modificato in modo semplice con +generici editor di testi o (per immagini composte da pixel) con generici +editor di immagini o (per i disegni) con qualche editor di disegni +ampiamente diffuso; la copia deve essere adatta al trattamento per la +formattazione o per la conversione in una variet@`a di formati atti alla +successiva formattazione. Una copia fatta in un formato di file, per il +resto trasparente, i cui marcatori o assenza di tali sono stati progettati +per intralciare o scoraggiare modifiche future da parte dei lettori non @`e +trasparente. Un formato immagine non @`e trasparente se viene usato per +rappresentare una notevole quantit@`a di testo. Una copia non ``trasparente'' +viene detta ``opaca''. + +Esempi di formati adatti per copie trasparenti sono l'@sc{ASCII} puro senza +marcatori, il formato di ingresso per Texinfo, il formato di ingresso per +La@TeX{}, @acronym{SGML} o @acronym{XML} accoppiati ad una @acronym{DTD} +pubblica e disponibile, e i formati conformi agli standard @acronym{HTML} +semplice, Postscript e @acronym{PDF} progettati per essere modificati +manualmente. Esempio di formati immagine trasparenti includono il +@acronym{PNG}, @acronym{XCF} e @acronym{JPG}. I formati opachi includono i +formati proprietari che possono essere letti e modificati solo con word +processor proprietari, @acronym{SGML} o @acronym{XML} per cui non @`e in +genere disponibile la @acronym{DTD} o gli strumenti per il trattamento, e i +formati @acronym{HTML}, Postscript e @acronym{PDF} generati automaticamente +da qualche word processor esclusivamente come output. + +La ``pagina del titolo'' di un libro stampato indica la pagina del titolo +stessa, pi@`u qualche pagina seguente per quanto necessario a contenere in +modo leggibile, il materiale che la licenza prevede che compaia nella +pagina del titolo. Per opere in formati in cui non sia contemplata +esplicitamente la pagina del titolo, con ``pagina del titolo'' si intende il +testo prossimo al titolo dell'opera, precedente l'inizio del corpo del +testo. + +Il termine ``editore'' indica qualunque persona o entit@`a che distribuisce al +pubblico copie del documento. + +Una sezione ``Intitolata XYZ'' significa una sottosezione con nome del +documento il cui titolo sia precisamente XYZ o che contenga XYZ in +parentesi dopo il testo che traduce XYZ in un'altra lingua (in questo caso +XYZ sta per uno specifico nome di sezione menzionato sotto, come per i +``Riconoscimenti'', ``Dediche'', ``Approvazioni'', o ``Storia''). Secondo questa +definizione, ``preservare il titolo'' di tale sezione quando si modifica il +documento, significa che essa rimane una sezione ``Intitolata XYZ''. + +Il Documento pu@`o includere dei limiti alla garanzia accanto alla nota +affermante l'applicazione di questa licenza al documento. Questi limiti +alla garanzia sono da considerare da includere come riferimento a questa +licenza, ma solo per quanto riguarda le limitazioni alla garanzia: ogni +altra implicazione che questi limiti alla garanzia possono avere @`e da +considerarsi nulla e non ha effetto sul significato di questa licenza. + +@item +COPIE LETTERALI + +Si pu@`o copiare e distribuire il documento con qualsiasi mezzo, con o senza +fini di lucro, purch@'e tutte le copie contengano questa licenza, le note di +copyright e l'avviso che questa licenza si applica al documento, e che non +si aggiungano altre condizioni al di fuori di quelle della licenza stessa. +Non si possono usare misure tecniche per impedire o controllare la lettura +o la produzione di copie successive alle copie che si producono o +distribuiscono. Si possono comunque accettare compensi per la copiatura. +Se si distribuiscono un numero sufficiente di copie si devono seguire +anche le condizioni della sezione 3. + +Alle stesse condizioni sopra menzionate si possono prestare copie e +mostrarle pubblicamente. + +@item +COPIARE IN NOTEVOLI QUANTIT@`A + +Se si pubblicano a mezzo stampa (o in formati che tipicamente posseggono +copertine) pi@`u di 100 copie del documento, e la nota della licenza +richiede uno o pi@`u testi di copertina, si devono includere nelle copie, in +modo chiaro e leggibile, tutti i testi di copertina indicati: il testo +della prima di copertina in prima di copertina e il testo di quarta di +copertina in quarta di copertina. Ambedue devono identificare l'editore +che pubblica il documento. La prima di copertina deve presentare il titolo +completo con tutte le parole che lo compongono egualmente visibili ed +evidenti. Si pu@`o aggiungere altro materiale alle copertine. Il copiare con +modifiche limitate alle sole copertine, purch@'e si preservino il titolo e +le altre condizioni viste in precedenza, @`e considerato alla stregua di +copiare alla lettera. + +Se il testo richiesto per le copertine @`e troppo voluminoso per essere +riprodotto in modo leggibile, se ne pu@`o mettere una prima parte (per +quanto ragionevolmente pu@`o stare) in copertina, e continuare il resto +nelle pagine immediatamente seguenti. + +Se si pubblicano o distribuiscono copie opache del documento in numero +superiore a 100, si deve anche includere una copia trasparente leggibile +da un calcolatore in ogni copia oppure menzionare in ogni copia opaca un +indirizzo di rete di calcolatori pubblicamente accessibile che utilizzi un +protocollo di rete standard pubblico, da cui si possa scaricare +liberamente una copia trasparente completa del documento, senza materiale +aggiuntivo. Se si adotta quest'ultima opzione, si deve prestare la giusta +attenzione, nel momento in cui si inizia la distribuzione in quantit@`a +elevata di copie opache, ad assicurarsi che la copia trasparente rimanga +accessibile all'indirizzo stabilito fino ad almeno un anno dopo l'ultima +distribuzione (direttamente o attraverso distributori o rivenditori) di +quell'edizione al pubblico. + +@`E caldamente consigliato, bench@'e non obbligatorio, contattare l'autore del +documento prima di distribuirne un numero considerevole di copie, per +metterlo in grado di fornire una versione aggiornata del documento. + +@item +MODIFICHE + +Si possono copiare e distribuire versioni modificate del documento +rispettando le condizioni delle precedenti sezioni 2 e 3, purch@'e la +versione modificata sia realizzata seguendo questa stessa licenza, con la +versione modificata che svolga il ruolo del ``documento'', cos@`{@dotless{i}} da estendere +la licenza sulla distribuzione e la modifica a chiunque ne possieda una +copia. Inoltre nelle versioni modificate si deve: + +@enumerate A +@item +Usare nella pagina del titolo (e nelle copertine se ce ne sono) un titolo +diverso da quello del documento, e da quelli di versioni precedenti (che +devono essere elencati nella sezione storia del documento ove presenti). +Si pu@`o usare lo stesso titolo di una versione precedente se l'editore di +quella versione originale ne ha dato il permesso. + +@item +Elencare nella pagina del titolo, come autori, una o pi@`u persone o gruppi +responsabili in qualit@`a di autori delle modifiche nella versione +modificata, insieme ad almeno cinque tra i principali autori del documento +(tutti gli autori principali se sono meno di cinque), a meno che questi +non abbiano acconsentito a liberarvi da quest'obbligo. + +@item +Dichiarare nella pagina del titolo il nome dell'editore della versione +modificata in qualit@`a di editore. + +@item +Conservare tutte le note di copyright +del documento originale. + +@item +Aggiungere un'appropriata nota di copyright per +le modifiche di seguito alle altre note di copyright. + +@item +Includere, immediatamente dopo la nota di copyright, una nota di licenza +che dia pubblicamente il permesso di usare la versione modificata nei +termini di questa licenza, nella forma mostrata nell'Addendum alla fine di +questo testo. + +@item +Preservare in tale nota di licenza l'elenco completo di sezioni non +modificabili e testi di copertina richiesti come previsto dalla licenza +del documento. + +@item +Includere una copia non modificata di questa licenza. + +@item +Conservare la sezione intitolata ``Storia'', e il suo titolo, e aggiungere +a questa un elemento che riporti almeno il titolo, l'anno, i nuovi autori, +e gli editori della versione modificata come figurano nella pagina del +titolo. Se non ci sono sezioni intitolate ``Storia'' nel documento, +crearne una che riporti il titolo, gli autori, gli editori del documento +come figurano nella pagina del titolo, quindi aggiungere un elemento che +descriva la versione modificata come detto in precedenza. + +@item +Conservare l'indirizzo in rete riportato nel documento, se c'@`e, al fine +del pubblico accesso ad una copia trasparente, e possibilmente l'indirizzo +in rete per le precedenti versioni su cui ci si @`e basati. Questi possono +essere collocati nella sezione ``Storia''. Si pu@`o omettere un indirizzo di +rete per un'opera pubblicata almeno quattro anni prima del documento +stesso, o se l'originario editore della versione cui ci si riferisce ne d@`a +il permesso. + +@item +In ogni sezione di ``Ringraziamenti'' o ``Dediche'', si conservi il titolo +della sezione, e all'interno della sezione tutta la sostanza e il tono di +ognuno dei ringraziamenti ai contributori e/o le dediche ivi contenute. + +@item +Si conservino inalterate le sezioni non modificabili del documento, nei +propri testi e nei propri titoli. I numeri della sezione o equivalenti non +sono considerati parte del titolo della sezione. + +@item +Si cancelli ogni sezione intitolata ``Approvazioni''. Tale sezione non pu@`o +essere inclusa nella versione modificata. + +@item +Non si cambi il titolo di sezioni esistenti in ``Approvazioni'' o in modo +tale che si possa creare confusione con i titoli di sezioni non +modificabili. + +@item +Si conservino tutti i limiti alla garanzia. +@end enumerate + + + +Se la versione modificata comprende nuove sezioni di primaria +importanza o appendici che ricadono in ``sezioni secondarie'', e non +contengono materiale copiato dal documento, si ha facolt@`a di rendere non +modificabili quante sezioni si voglia. Per fare ci@`o si aggiunga il loro +titolo alla lista delle sezioni non modificabili nella nota di licenza +della versione modificata. Questi titoli devono essere distinti dai titoli +di ogni altra sezione. + +Si pu@`o aggiungere una sezione intitolata ``Approvazioni'', a patto che non +contenga altro che le approvazioni alla versione modificata prodotte da +vari soggetti--per esempio, affermazioni di revisione o che il testo @`e +stato approvato da una organizzazione come la definizione normativa di uno +standard. + +Si pu@`o aggiungere un brano fino a cinque parole come testo di prima di +copertina e un brano fino a 25 parole come testo di quarta di copertina, +alla fine dell'elenco dei testi di copertina nella versione modificata. +Solamente un brano del testo di prima di copertina e uno del testo di +quarta di copertina possono essere aggiunti (anche con adattamenti) da +ciascuna persona o organizzazione. Se il documento include gi@`a un testo di +copertina per la stessa copertina, precedentemente aggiunto o adattato da +qualunque fruitore o dalla stessa organizzazione nel nome della quale si +agisce, non se ne pu@`o aggiungere un altro, ma si pu@`o rimpiazzare il +vecchio ottenendo l'esplicita autorizzazione dall'editore precedente che +aveva aggiunto il testo di copertina. + +L'autore/i e l'editore/i del documento non danno, tramite questa licenza, +il permesso di usare i loro nomi per pubblicizzare o asserire, anche +implicitamente, la loro approvazione di ogni versione modificata. + +@item +COMBINAZIONE DI DOCUMENTI + +Si pu@`o combinare il documento con altri pubblicati con questa licenza, +seguendo i termini definiti nella precedente sezione 4 per le versioni +modificate, a patto che si includa l'insieme di tutte le sezioni non +modificabili di tutti i documenti originali, senza modifiche, e si +elenchino tutte come sezioni non modificabili della combinazione di +documenti nella licenza della stessa, mantenendo tutti i limiti alla +garanzia. + +Nella combinazione @`e necessaria una sola copia di questa licenza, e pi@`u +sezioni non modificabili possono essere rimpiazzate da una singola copia +se identiche. Se ci sono pi@`u sezioni non modificabili con lo stesso nome +ma contenuti differenti, si renda unico il titolo di ciascuna sezione +aggiungendovi, alla fine e tra parentesi, il nome dell'autore o editore +della sezione, se noti, o altrimenti un numero distintivo. Si facciano gli +stessi aggiustamenti ai titoli delle sezioni nell'elenco delle sezioni non +modificabili nella nota di copyright della combinazione. + +Nella combinazione si devono unire le varie sezioni intitolate ``Storia'' +nei vari documenti originali di partenza per formare una unica sezione +intitolata ``Storia''; allo stesso modo si unisca ogni sezione intitolata +``Ringraziamenti'', e ogni sezione intitolata ``Dediche''. Si devono eliminare +tutte le sezioni intitolate ``Approvazioni''. + +@item +RACCOLTE DI DOCUMENTI + +Si pu@`o produrre una raccolta che consista del documento e di altri +documenti rilasciati sotto questa licenza, e rimpiazzare le singole copie +di questa licenza nei vari documenti con una sola inclusa nella raccolta, +solamente se si seguono le regole fissate da questa licenza per le copie +alla lettera come se si applicassero a ciascun documento. + +Si pu@`o estrarre un singolo documento da tale raccolta e distribuirlo +separatamente sotto questa licenza, solo se si inserisce una copia di +questa licenza nel documento estratto e se si seguono tutte le altre +regole fissate da questa licenza per le copie alla lettera del documento. + +@item +AGGREGAZIONE A LAVORI INDIPENDENTI + +Un'unione del documento o sue derivazioni con altri documenti o lavori +separati o indipendenti, all'interno di, o a formare un, archivio o un +supporto, per la memorizzazione o la distribuzione, viene chiamato un +``aggregato'' se il copyright risultante dall'unione non viene usato per +limitare i diritti legali degli utilizzatori oltre a ci@`o che viene +permesso dai singoli lavori. Quando il documento viene incluso in un +aggregato, questa licenza non si applica ad altri lavori nell'aggregato +che non siano essi stessi dei lavori derivati dal documento. + +Se le esigenze del testo di copertina della sezione 3 sono applicabili a +queste copie del documento allora, se il documento @`e inferiore alla met@`a +dell'intero aggregato i testi di copertina del documento possono essere +piazzati in copertine che delimitano il documento all'interno +dell'aggregato, o dell'equivalente elettronico delle copertine se il +documento @`e in un formato elettronico. Altrimenti devono apparire nella +copertina dell'intero aggregato. + +@item +TRADUZIONE + +La traduzione @`e considerata un tipo di modifica, di conseguenza si possono +distribuire traduzioni del documento nei termini della sezione 4. +Rimpiazzare sezioni non modificabili con traduzioni richiede un +particolare permesso da parte dei detentori del copyright, ma @`e possibile +includere la traduzione di parti o di tutte le sezioni non modificabili in +aggiunta alle versioni originali di queste sezioni. @`E possibile includere +una traduzione di questa licenza, di tutte le avvertenze del documento e +di tutti i limiti di garanzia, a condizione che si includa anche la +versione originale in inglese della licenza completa, comprese le +avvertenze e limitazioni di garanzia. In caso di discordanza tra la +traduzione e la versione originale inglese di questa licenza o avvertenza +o limitazione di garanzia, prevale sempre la versione originale inglese. + +Se una sezione del documento viene titolata ``Riconoscimenti'', ``Dediche'', o +``Storia'', il requisito (sezione 4) di preservare il titolo (sezione 1) +richieder@`a tipicamente il cambiamento del titolo. + +@item +CESSAZIONE DELLA LICENZA + +Non si pu@`o sublicenziare il documento, copiarlo, modificarlo, o +distribuirlo al di fuori dei termini espressamente previsti da questa +licenza. Ogni altro tentativo di applicare una licenza al documento, +copiarlo, modificarlo, o distribuirlo @`e nullo e pone fine automaticamente +ai diritti previsti da questa licenza. + +In ogni caso, se cessano tutte le violazioni di questa Licenza, allora la +specifica licenza di un particolare detentore del copyright viene +ripristinata (a) in via provvisoria, a meno che e fino a quando il +detentore del copyright non faccia estinguere esplicitamente e +definitivamente la licenza, e (b) in via permanente se il detentore del +copyright non notifica in alcun modo la violazione entro 60 giorni dalla +cessazione della licenza. + +Inoltre, la licenza di un dato detentore del copyright viene ripristinata +in maniera permanente se quest'ultimo notifica la violazione in maniera +adeguata, se si tratta della prima volta che si riceve una notifica di +violazione della licenza (per qualsiasi opera) dallo stesso detentore di +copyright, e se la violazione viene corretta entro 30 giorni dalla data di +ricezione della notifica di violazione. + +La cessazione dei diritti come specificato in questa sezione non provoca +la cessazione delle licenze di terze parti che abbiano ricevuto copie o +diritti secondo questa licenza. Se i diritti sono cessati e non sono stati +ristabiliti in via permanente, la ricezione di una copia dello stesso +materiale, in tutto o in parte, non d@`a alcun diritto ad utilizzarlo. + +@item +REVISIONI FUTURE DI QUESTA LICENZA + +La Free Software Foundation pu@`o occasionalmente pubblicare versioni nuove +o rivedute della Licenza per Documentazione Libera GNU. Le nuove versioni +saranno simili nello spirito alla versione attuale ma potrebbero +differirne in qualche dettaglio per affrontare nuovi problemi e concetti. +Si veda @uref{http://www.gnu.org/copyleft/}. + +Ad ogni versione della licenza viene dato un numero che la distingue. Se +il documento specifica che si riferisce ad una versione particolare della +licenza ``o ogni versione successiva'', si ha la possibilit@`a di seguire +termini e condizioni sia della versione specificata che di ogni versione +successiva pubblicata (non come bozza) dalla Free Software Foundation. Se +il documento non specifica un numero di versione particolare di questa +licenza, si pu@`o scegliere ogni versione pubblicata (non come bozza) dalla +Free Software Foundation. Se il documento specifica che un delegato pu@`o +decidere quale futura versione di questa licenza pu@`o essere utilizzata, +allora la dichiarazione pubblica di accettazione della versione, da parte +del delegato, autorizza in maniera permanente a scegliere tale versione +per il documento. + +@item +CAMBIO DI LICENZA + +Il termine ``sito per la collaborazione massiva multiautore'' (o ``sito +MMC'') +indica qualsiasi server web che pubblica opere sottoponibili a copyright e +fornisce a chiunque appositi strumenti per modificare tali opere. Un wiki +pubblico modificabile da chiunque @`e un esempio di server in questione. Una +``collaborazione massiva multiautore'' (o ``MMC'') contenuta nel sito indica +un qualunque insieme di opere sottoponibili a copyright pubblicate sul +sito MMC. + +Il termine ``CC-BY-SA'' indica la licenza Creative Commons Attribution-Share +Alike 3.0 pubblicata dalla Creative Commons Corporation, un'organizzazione +senza fini di lucro con sede principale a San Francisco, California, come +anche le future versioni di tale licenza pubblicate dalla stessa +organizzazione. + +``Incorporare'' significa pubblicare o ripubblicare un documento in tutto o +in parte, come parte di un altro documento. + +Una MMC @`e ``qualificata a cambiare questa licenza'' se ha adottato questa +licenza e se tutte le opere precedentemente pubblicate con questa licenza +altrove rispetto alla MMC e successivamente incorporate del tutto o in +parte nella MMC (1) non hanno testo di copertina o sezioni invarianti e +(2) sono state incorporate prima del 1° Novembre 2008. + +L'operatore di un sito MMC pu@`o ripubblicare un MMC contenuto nel sito con +una CC-BY-SA nello stesso sito in qualsiasi momento prima del 1° Agosto +2009, da parte di una MMC qualificata a cambiare questa licenza. + +@end enumerate + +@c fakenode --- for prepinfo +@unnumberedsec ADDENDUM: Come usare questa licenza per i vostri documenti + +Per applicare questa licenza ad un documento che si @`e scritto, si includa +una copia della licenza nel documento e si inserisca la seguente nota di +copyright appena dopo la pagina del titolo: + +@smallexample +@group + Copyright (C) @var{<anno>} @var{<il vostro nome>} + @`E permesso copiare, distribuire e/o modificare questo documento + seguendo i termini della ``Licenza per documentazione libera GNU'', versione 1.3 + o ogni versione successiva pubblicata dalla Free Software Foundation; + senza sezioni non modificabili, senza testi di prima di copertina e di quarta di copertina. + Una copia della licenza @`e inclusa nella sezione intitolata + ``Licenza per la documentazione libera GNU''. +@end group +@end smallexample + +Se ci sono sezioni non modificabili, testi di prima di copertina e di +quarta di copertina, scrivere nella parte ``with@dots{} di copertina'' il testo seguente: + +@smallexample +@group + con le seguenti sezioni non modificabili @var{lista dei loro titoli}, + con i seguenti testi di prima di copertina @var{elenco}, + e con i seguenti testi di quarta di copertina @var{elenco}, +@end group +@end smallexample + +Se esistono delle sezioni non modificabili ma non i testi di copertina, o +qualche altra combinazione dei tre elementi sopra riportati, fondere +assieme le due alternative in modo da conformarsi alla situazione descritta. + +Se il vostro documento contiene esempi non banali di programma in codice +sorgente si raccomanda di rilasciare gli esempi contemporaneamente +applicandovi anche una licenza di software libero di vostra scelta, come +per esempio la Licenza Pubblica Generica GNU, al fine di permetterne l'uso +come software libero. + +@end ifclear + +@ifnotdocbook +@node Indice analitico +@unnumbered Indice analitico +@end ifnotdocbook +@printindex cp + +@bye + +Unresolved Issues: +------------------ +1. From ADR. + + Robert J. Chassell points out that awk programs should have some indication + of how to use them. It would be useful to perhaps have a "programming + style" section of the manual that would include this and other tips. + +Consistency issues: + /.../ regexps are in @code, not @samp + ".." strings are in @code, not @samp + no @print before @dots + values of expressions in the text (@code{x} has the value 15), + should be in roman, not @code + Use TAB and not tab + Use ESC and not ESCAPE + Use space and not blank to describe the space bar's character + The term "blank" is thus basically reserved for "blank lines" etc. + To make dark corners work, the @value{DARKCORNER} has to be outside + closing `.' of a sentence and after (pxref{...}). + " " should have an @w{} around it + Use "non-" only with language names or acronyms, or the words bug and option and null + Use @command{ftp} when talking about anonymous ftp + Use uppercase and lowercase, not "upper-case" and "lower-case" + or "upper case" and "lower case" + Use "single precision" and "double precision", not "single-precision" or "double-precision" + Use alphanumeric, not alpha-numeric + Use POSIX-compliant, not POSIX compliant + Use --foo, not -Wfoo when describing long options + Use "Bell Laboratories", but not "Bell Labs". + Use "behavior" instead of "behaviour". + Use "coprocess" instead of "co-process". + Use "zeros" instead of "zeroes". + Use "nonzero" not "non-zero". + Use "runtime" not "run time" or "run-time". + Use "command-line" as an adjective and "command line" as a noun. + Use "online" not "on-line". + Use "whitespace" not "white space". + Use "Input/Output", not "input/output". Also "I/O", not "i/o". + Use "lefthand"/"righthand", not "left-hand"/"right-hand". + Use "workaround", not "work-around". + Use "startup"/"cleanup", not "start-up"/"clean-up" + Use "filesystem", not "file system" + Use @code{do}, and not @code{do}-@code{while}, except where + actually discussing the do-while. + Use "versus" in text and "vs." in index entries + Use @code{"C"} for the C locale, not ``C'' or @samp{C}. + The words "a", "and", "as", "between", "for", "from", "in", "of", + "on", "that", "the", "to", "with", and "without", + should not be capitalized in @chapter, @section etc. + "Into" and "How" should. + Search for @dfn; make sure important items are also indexed. + "e.g." should always be followed by a comma. + "i.e." should always be followed by a comma. + The numbers zero through ten should be spelled out, except when + talking about file descriptor numbers. > 10 and < 0, it's + ok to use numbers. + For most cases, do NOT put a comma before "and", "or" or "but". + But exercise taste with this rule. + Don't show the awk command with a program in quotes when it's + just the program. I.e. + + { + .... + } + + not + awk '{ + ... + }' + + Do show it when showing command-line arguments, data files, etc, even + if there is no output shown. + + Use numbered lists only to show a sequential series of steps. + + Use @code{xxx} for the xxx operator in indexing statements, not @samp. + Use MS-Windows not MS Windows + Use MS-DOS not MS DOS + Use an empty set of parentheses after built-in and awk function names. + Use "multiFOO" without a hyphen. + Use "time zone" as two words, not "timezone". + +Date: Wed, 13 Apr 94 15:20:52 -0400 +From: rms@gnu.org (Richard Stallman) +To: gnu-prog@gnu.org +Subject: A reminder: no pathnames in GNU + +It's a GNU convention to use the term "file name" for the name of a +file, never "pathname". We use the term "path" for search paths, +which are lists of file names. Using it for a single file name as +well is potentially confusing to users. + +So please check any documentation you maintain, if you think you might +have used "pathname". + +Note that "file name" should be two words when it appears as ordinary +text. It's ok as one word when it's a metasyntactic variable, though. + +------------------------ +ORA uses filename, thus the macro. + +Suggestions: +------------ + +Better sidebars can almost sort of be done with: + + @ifdocbook + @macro @sidebar{title, content} + @inlinefmt{docbook, <sidebar><title>} + \title\ + @inlinefmt{docbook, </title>} + \content\ + @inlinefmt{docbook, </sidebar>} + @end macro + @end ifdocbook + + + @ifnotdocbook + @macro @sidebar{title, content} + @cartouche + @center @b{\title\} + + \content\ + @end cartouche + @end macro + @end ifnotdocbook + +But to use it you have to say + + @sidebar{Title Here, + @include file-with-content + } + +which sorta sucks. + +TODO: +Check that all dark corners are indexed properly. + |